Search code examples
javascriptes6-promise

How the Promise is resolved in given JavaScript code using Array.reduce()?


Please refer the following JavaScript code:

var arr = [30, 40, 10, 50, 20];
var fun = function(n) {
  console.log("Before Promise => n: " + n);
  return new Promise(resolve => {
    console.log("After Promise => n: " + n);
    setTimeout(() => {
      console.log("Promise Resolved => n: " + n);
      resolve(0);
    }, n * 30);
  });
}
arr.reduce((p, v) => p.then(fun(v)), Promise.resolve(0));

1. Please correct me if I am wrong that Array.reduce() will reduce the above as following Promise chain:

Promise.resolve(0).then(fun(30)).then(fun(40)).then(fun(10)).then(fun(50)).then(fun(20)).

2. Why the output is not as below:

Promise Resolved => n: 30
Promise Resolved => n: 40
Promise Resolved => n: 10
Promise Resolved => n: 50
Promise Resolved => n: 20

3. And why the output is as above if I change n*30 with fixed time say 500 ?


Solution

  • .then accepts a function as a parameter, but you're doing:

    p.then(fun(v))
    

    This invokes fun immediately, without waiting for p to resolve, and passes the returned Promise to .then. It's like doing

    Promise.then(Promise.resolve(6))
             //  ^^^ but .then only accepts a function as a parameter
    

    which doesn't make sense.

    Change to a callback which, when called, calls fun and returns fun's Promise:

    var arr = [30, 40, 10, 50, 20];
    var fun = function(n) {
        console.log("Before Promise => n: " + n);
        return new Promise(resolve => {
            console.log("After Promise => n: " + n);
            setTimeout(() => {
                console.log("Promise Resolved => n: " + n);
                resolve(0);
            }, n*30);
        });
    }
    arr.reduce((p, v) => p.then(() => fun(v)), Promise.resolve(0));
    //                          ^^^^^^