Search code examples
javascriptes6-promise

.then() is getting executed before Promise.all()


I'm learning promises and I'm trying to chain them using the following code. In this, .then() gets executed first:

function myPromise1()
{
  console.log("Promise", 1);
  return Promise.all([
    new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log("This should be before 'Yay!' for 1");
        resolve(1);
      }, 3000);
    }),
    new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log("This should be before 'Yay!' for 2");
        resolve(2);
      }, 3000);
    })
  ]);
}

function myPromise2() {
  console.log("Promise", 2);
  var arr = [1,2,3,4];
  return Promise.all(arr.map(i => {
    new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log("This should be before 'Yay!' for i= " + i);
        resolve("Success!" + i);
      }, 3000)
    })
  }));
}

function anotherPromise(val) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(val);
    }, 3000);
  });
}

myPromise2()
  .then((msg) => {
  console.log("Yay! " + msg);
  return anotherPromise("Awesome!");
})
  .then((msg2) => {
  console.log("This should be Awesome:", msg2);
})
  .catch((err) => {
  console.log("Uh no, this is a lie --->", err);
});

console.log("This will print as second line after the method name, even though its the last line.");

This is the output:

Promise 2
This will print as second line after the method name, even though its the last line.
Yay! ,,,
This should be before 'Yay!' for i= 1
This should be before 'Yay!' for i= 2
This should be before 'Yay!' for i= 3
This should be before 'Yay!' for i= 4
This should be Awesome: Awesome!

Process finished with exit code 0

As you can see, .then() gets called before and hence the values are not returned.

However, if I call myPromise1() instead, I get the desired output. The values are returned too and .then() gets called after both the promises.

How can I fix the issue with myPromise2()?


Solution

  • You are forgetting to return from map method here:

    function myPromise2() {
      console.log("Promise", 2);
      var arr = [1,2,3,4];
      return Promise.all(arr.map(i => {
      /* missing return ---> */  new Promise((resolve, reject) => { 
          setTimeout(() => {
            console.log("This should be before 'Yay!' for i= " + i);
            resolve("Success!" + i);
          }, 3000)
        })
      }));
    }
    

    function myPromise1() {
      console.log("Promise", 1);
      return Promise.all([
        new Promise((resolve, reject) => {
          setTimeout(() => {
            console.log("This should be before 'Yay!' for 1");
            resolve(1);
          }, 3000);
        }),
        new Promise((resolve, reject) => {
          setTimeout(() => {
            console.log("This should be before 'Yay!' for 2");
            resolve(2);
          }, 3000);
        })
      ]);
    }
    
    function myPromise2() {
      console.log("Promise", 2);
      var arr = [1, 2, 3, 4];
      return Promise.all(arr.map(i => {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            console.log("This should be before 'Yay!' for i= " + i);
            resolve("Success!" + i);
          }, 3000)
        })
      }));
    }
    
    function anotherPromise(val) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(val);
        }, 3000);
      });
    }
    
    myPromise2()
      .then((msg) => {
        console.log("Yay! " + msg);
        return anotherPromise("Awesome!");
      })
      .then((msg2) => {
        console.log("This should be Awesome:", msg2);
      })
      .catch((err) => {
        console.log("Uh no, this is a lie --->", err);
      });
    
    console.log("This will print as second line after the method name, even though its the last line.");