Modermo
Modermo

Reputation: 1992

Why does console.log() execute immediately in a Promises's resolve() function?

Take the following, for example:

function sayHello () {
  return new Promise( function(resolve, reject) {
    console.log('Were inside the promise');

    return resolve(5);
  })
}

sayHello().then(function(success){
  console.log(success)
})

console.log('Im outside the promise')

We know that this executes, in this order:

Were inside the promise
Im outside the promise
5

And then, for something like:

function sayHello () {
  return new Promise( function(resolve, reject) {
    console.log('Were inside the promise');

    return resolve((function(){
      return 5
    })());
  })
}

sayHello().then(function(success){
  console.log(success)
})

console.log('Im outside the promise')

It returns the same sequence of console.log output as the former example. Great, makes sense; whatever the value in resolve is, gets piped as an argument when then() executes.

Why however, when I have something like the below:

function sayHello () {
  return new Promise( function(resolve, reject) {
    console.log('Were inside the promise');

    return resolve(console.log(5));
  })
}

sayHello().then(function(success){
  console.log(success)
})

console.log('Im outside the promise')

Do I get this order:

Were inside the promise
5
Im outside the promise

Upvotes: 1

Views: 735

Answers (2)

axiac
axiac

Reputation: 72206

The documentation of Promise constructor explains:

Syntax

new Promise( /* executor */ function(resolve, reject) { ... } );

Parameters

executor

A function that is passed with the arguments resolve and reject. The executor function is executed immediately by the Promise implementation, passing resolve and reject functions (the executor is called before the Promise constructor even returns the created object). [...]
The executor normally initiates some asynchronous work, and then, once that completes, either calls the resolve function to resolve the promise or else rejects it if an error occurred. [...]
The return value of the executor is ignored.

Armed with the knowledge exposed above, your code should be something like:

function sayHello () {
  return new Promise(function(resolve, reject) {
    // Start an asynchronous operation
    // This example uses setTimeout() to simulate a lengthy operation (1 second)
    // but in a real program you probably start a network request, 
    // a database operation or a file system operation
    setTimeout(function() {
        // This is when the async operation completes
        console.log('Were inside the promise');
        // Fulfill the promise, set '5' as the value returned by the promise
        resolve(5);
    }, 1000);
  });
}


sayHello().then(function(success){
  console.log(success);
});

console.log('Im outside the promise');

Upvotes: 2

raina77ow
raina77ow

Reputation: 106385

While resolver function is called in the next 'tick', its argument is evaluated immediately. That's why you see console.log(5) executed before then callback in your third snippet example. This becomes more clear if you change your second snippet into this:

function sayHello() {
  return new Promise(function(resolve, reject) {
    console.log('Were inside the promise');
    return resolve((function() {
      console.log('Inside resolver argument');
      return 5
    })());
  })
}
sayHello().then(function(success) {
  console.log(success)
});
console.log('Im outside the promise');

Upvotes: 2

Related Questions