Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why this chain of promises immediately resolves?

Can someone explain to me why the resulting promise (d) from the code below is resolved immediately?

//promises that are never resolved nor rejected
var a = new Promise(function(r,re){});
var b = new Promise(function(r,re){});
var c = new Promise(function(r,re){});

var d = [a, b, c].reduce(function (previousPromise, promise) {
    return previousPromise.then(promise);
  }, Promise.resolve());

I'm creating an array of promises that are pending forever, so the resulting promise should also be pending forever as it waits for all subsequent promises to finish (as presented here). I've been using promises for a while now, but I'm clearly missing something here.

Chrome DevTools - promises code executed

like image 623
Konrad Dzwinel Avatar asked Aug 18 '15 08:08

Konrad Dzwinel


People also ask

What makes chaining of promises possible?

Chaining. A common need is to execute two or more asynchronous operations back to back, where each subsequent operation starts when the previous operation succeeds, with the result from the previous step. We accomplish this by creating a promise chain.

What is a promise 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.

What happens to promises that never resolve?

Since you don't call resolve() , that code will never execute and thus the console will not print "done". The body of the Promise is, however, executed immediately, and since it's empty, there is nothing left for the program to execute!

How do you wait for the promise to resolve?

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.


1 Answers

then doesn't take a Promise as an input, it takes 2 functions, 1 for fulfillment and 1 for rejection.

The reason d is resolved is due to the fact that calling .then with a non-callable value (even a number literal - 1, or undefined) causes the onFulfilled function to be replace by "Identity", which simply re-fulfills with whatever value was resolved in the previous step. See PerformPromiseThen

Try like this:

//promises that are never resolved nor rejected
var a = function() { return new Promise(function(r,re){}); };
var b = function() { return new Promise(function(r,re){}); };
var c = function() { return new Promise(function(r,re){}); };
// or simply, a = b = c after setting the function for c

var d = [a, b, c].reduce(function (previousPromise, fn) {
    return previousPromise.then(fn, /* not passing a rejection handler... */);
  }, Promise.resolve());

Or alternatively...

//promises that are never resolved nor rejected
var a = new Promise(function(r,re){});
var b = new Promise(function(r,re){});
var c = new Promise(function(r,re){});

var d = [a, b, c].reduce(function (previousPromise, promise) {
    return previousPromise.then(function() {return promise;});
  }, Promise.resolve());

And since you're using promises & ES6, you could be more concise:

let a = new Promise(() => {});
let b = new Promise(() => {});
let c = new Promise(() => {});

let d = [a, b, c].reduce((previousPromise, promise) =>
  previousPromise.then(() => promise),
  Promise.resolve());
like image 127
Amit Avatar answered Sep 20 '22 00:09

Amit