Search code examples
javascriptpromisees6-promise

Synchronously executing promises saved in variables


I drafted a code example to better understand Promise chaining and found myself quite confused about what's going on here.

Let's say we have two variables which store Promises:

const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve('promise 1');
  }, 1000);
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve('promise 2');
  }, 1000);
});

Then we chain them like that:

promise1
  .then(data => {
      console.log(data);
      return promise2;
  })
  .then(data => {
      console.log(data);
  });

The two console.log's seem to arrive simultaneously, although I would expect a 1 sec pause between them. Behavior is the same if I create functions which return promises and chain them instead:

function firePromise1() {
    return promise1;
} 

function firePromise2() {
    return promise2;
} 

firePromise1()
    .then(data => {
        console.log(data);
        return firePromise2();
    })
   .then(data => {
        console.log(data);
   });

And only if I create a promise "on the go" (either inside the function called in promise chain or in then() block itself), I see promises resolved one after another, with 1 sec interval:

promise1
    .then(data => {
    console.log(data);
    return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve('promise 2');
          }, 1000);
        });
    })
    .then(data => {
      console.log(data); 
    });

Can someone please explain why it works that way? Is it about how JS initializes variables and somehow connected to the fact that "Promise executes immediately" (https://hackernoon.com/functional-javascript-resolving-promises-sequentially-7aac18c4431e)? I looked deep into different resources and docs but still seem to miss something important or even obvious... Thanks!


Solution

  • For the first two promise chains involving the declaration of promise1 and promise2 as variables, that is :

    const promise1 = new Promise((resolve, reject) => {
        setTimeout(() => {
        resolve('promise 1');
      }, 1000);
    });
    
    const promise2 = new Promise((resolve, reject) => {
        setTimeout(() => {
        resolve('promise 2');
      }, 1000);
    });
    

    When you declare and assign variables, the right hand side of the assignment operator evaluates instantly, that is, both setTimeout functions start immediately. It has nothing to do with a promise 'being executed'. You can test this by having a console.log("Print me!") inside both setTimeout functions.

    If you declared the promises inside the following functions and then created a then() chain you would have seen a one second delay between the logging of promise1 and promise2.

    function prom1(){
        return new Promise((resolve, reject) => {
            setTimeout(() => {
            resolve('promise 1');
          }, 1000);
        });
    }
    function prom2(){ 
        return new Promise((resolve, reject) => {
            setTimeout(() => {
            resolve('promise 2');
          }, 1000);
        });
    }