I need to create a JavaScript Promise that will not resolve until a specific condition is true. Let's say I have a 3rd party library, and I need to wait until a certain data condition exists within that library.
The scenario I am interested in is one where there is no way to know when this condition is satisfied other than by simply polling.
I can create a promise that waits on it - and this code works, but is there a better or more concise approach to this problem?
function ensureFooIsSet() { return new Promise(function (resolve, reject) { waitForFoo(resolve); }); } function waitForFoo(resolve) { if (!lib.foo) { setTimeout(waitForFoo.bind(this, resolve), 30); } else { resolve(); } }
Usage:
ensureFooIsSet().then(function(){ ... });
I would normally implement a max poll time, but didn't want that to cloud the issue here.
You can use the async/await syntax or call the . then() method on a promise to wait for it to resolve. Inside of functions marked with the async keyword, you can use await to wait for the promises to resolve before continuing to the next line of the function. Copied!
Promise. all does not improve performance. It's the "not waiting for the first promise before starting the second task" that improves performance (if done correctly).
resolve() The Promise. resolve() method "resolves" a given value to a Promise . If the value is a promise, that promise is returned; if the value is a thenable, Promise. resolve() will call the then() method with two callbacks it prepared; otherwise the returned promise will be fulfilled with the value.
The reason the promise is executing before your timeout is that the promise isn't actually waiting for anything so it resolved right away. @frankies That has more to do with the way Promises are queued and resolved. The focus of my answer is the difference between setTimeout and Promise .
A small variation would be to use a named IIFE so that your code is a little more concise and avoids polluting the external scope:
function ensureFooIsSet() { return new Promise(function (resolve, reject) { (function waitForFoo(){ if (lib.foo) return resolve(); setTimeout(waitForFoo, 30); })(); }); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With