Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a version of setTimeout that returns an ES6 promise?

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.

like image 217
Michael Kropat Avatar asked Dec 13 '15 19:12

Michael Kropat


People also ask

Does setTimeout return promise?

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.

How do you set a promise on setTimeout?

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.

Which is faster setTimeout or promise?

Short answer Promises have better priority than setTimeout callback function in event loop stack(or how i understand it).

Are promises introduced in ES6?

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.


2 Answers

In Browsers

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)); 

In Node

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.

like image 160
Benjamin Gruenbaum Avatar answered Sep 20 '22 04:09

Benjamin Gruenbaum


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.

like image 43
Michael Kropat Avatar answered Sep 20 '22 04:09

Michael Kropat