Similar to this question, but rather than asking about how promises work in general, I specifically want to know:
What is the standard/best way to wrap setTimeout in something that returns a Promise? I'm thinking something like Angular's $timeout
function, but not Angular specific.
All it does is use the Promise constructor to wrap setTimeout() and resolve the promise after delay ms. This can be a useful tool when some code has to stall for a given amount of time.
To make a promise from setTimeout with JavaScript, we can use the Promise constructor. const later = (delay) => { return new Promise((resolve) => { setTimeout(resolve, delay); }); }; to create the later function which returns a promise we create with the Promise constructor.
Short answer Promises have better priority than setTimeout callback function in event loop stack(or how i understand it).
ES6 comes to your rescue by introducing the concept of promises. Promises are "Continuation events" and they help you execute the multiple async operations together in a much cleaner code style.
First of all no - there is no built in for this. Lots of libraries that enhance ES2015 promises like bluebird whip with it.
I think the other answer conflates executing the function and a delay, it also creates timeouts that are impossible to cancel. I'd write it simply as:
function delay(ms){ var ctr, rej, p = new Promise(function (resolve, reject) { ctr = setTimeout(resolve, ms); rej = reject; }); p.cancel = function(){ clearTimeout(ctr); rej(Error("Cancelled"))}; return p; }
Then you can do:
delay(1000).then(/* ... do whatever */);
Or
doSomething().then(function(){ return delay(1000); }).then(doSomethingElse);
If we only want the basic functionality in ES2015, it's even simpler as:
let delay = ms => new Promise(r => setTimeout(r, ms));
You can use util.promisify
on setTimeout
to get a delay
function back - meaning you don't have to use the new Promise
constructor anymore.
Here's how I'd implement it:
function delay(duration, func) { var args = Array.prototype.slice.call(arguments, 2); return new Promise(function (resolve) { setTimeout(function () { resolve(func.apply(null, args)); }, duration); }); }
(ES5-syntax intentionally chosen)
But maybe there's a common library that already does this, or a better way to do it.
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