-3

Let's say we have some Promise for we knew it resolves at some point. Now I have sync code (ag. no await possible) called repeatedly (eg. onAnimationFrame). How to use the result of the promise there, if it is fullfilled?

Like (JS pseudocode):

let promise=FetchSomething();
let updater = ()=>{
  drawSomething();
  if(promise IS FULLFILLED)  // how to know if fullfilled?
    drawThing(RESULT OF promise); // how to get the result here?
  requestAnimationFrame(updater);
}
updater();
dronus
  • 10,774
  • 8
  • 54
  • 80
  • 4
    can't you just use the `.then` function? E.g. `FetchSomething().then((result) => drawThing(result));` – Glubus Sep 01 '23 at 14:43
  • No, it will not happen at the requestAnimationFrame handler then, but at some uncontrolled point in time. – dronus Sep 01 '23 at 14:44
  • 3
    `requestAnimationFrame` is not synchronous – Jared Smith Sep 01 '23 at 14:44
  • 1
    You can just put the `requestAnimationFrame` inside the `.then`. – starikcetin Sep 01 '23 at 14:46
  • "No, it will not happen at the requestAnimationFrame handler then, but at some uncontrolled point in time." Yes, that will happen either way, because you can't e.g. block a thread to wait for the Promise to resolve, and even if you could you'd have to coordinate it with the main thread somehow. It isn't clear what you are asking here, or what your actual use case is that would let us suggest a more appropriate solution. rAF *queues up a deferred call*, just like `Promise.prototype.then`, so what's the difference? – Jared Smith Sep 01 '23 at 14:48
  • What part of this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#chained_promises is not clear or needs more explanation? Especially this part perhaps https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#chained_promises – Mark Schultheiss Sep 01 '23 at 14:48
  • To be clear it has to do with the promise call back `then(onFulfilled, onRejected)` one for each... – Mark Schultheiss Sep 01 '23 at 14:52
  • I think in OP's use case the updater function is called many times per second, and needs to start drawing after the result of an async call. I think you could have some outside variable `let result;` and then `FetchSomething().then((r) => result = r)`, and in your `updater` function: `if(result != null) { drawThing(result) }` – Glubus Sep 01 '23 at 15:17

2 Answers2

2

The easiest way is to set a variable yourself:

let promise = FetchSomething();
let done = false

/* variable will be set once promise settled */
promise.then(() => {
    done = true
})

let updater = () => {
  drawSomething();

  if (done) {  
      drawThing(/* RESULT OF promise */); 
  }

  requestAnimationFrame(updater);
}

updater();

You can do the same with the result, i.e.:

let promise = FetchSomething();
let done = false
let result = null

promise.then((value) => {
    done = true
    result = value
})

let updater = () => {
  drawSomething();

  if (done) {  
      drawThing(result); 
  }

  requestAnimationFrame(updater);
}

updater();
Marco
  • 7,007
  • 2
  • 19
  • 49
-1

Perhaps this simple promise using your names will illustrate:

// fake 
function FetchSomething(myfoo) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(myfoo);
    }, 2000);
  });
}

function drawSomething(val) {
  console.log('draw', val);
}

function drawThing(val) {
  console.log('drawthing', val);
}

function woops(val) {
  console.log(val);
}

let handleFulfilled = (val) => {
  drawSomething(val);
  drawThing(val);
  requestAnimationFrame(updater);
}

let handleRejected = (val) => {
  drawSomething(val);
  woops(val);
  requestAnimationFrame(updater);
}
let goodfoo = "good foo";

function updateFun(v) {
  let fetchPromise = FetchSomething(v);

  fetchPromise.then(handleFulfilled, handleRejected);
  let t = new Date(Date.now()).getSeconds();
  setTimeout(function() {
    updateFun(goodfoo + t)
  }, 5000);
}
updateFun(goodfoo);
Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100