PunDefeated PunDefeated - 1 month ago 8
Node.js Question

Promises .then(async()) versus .then(function(){return async()})

I'm trying to figure out why the following behavior happens, as well as what the benefit might be. Using bluebird as the promise implementation.

printValue = function (value){
return new Promise(function(resolve, reject){
console.log(value);
resolve(value)
});
}

describe.only('promises', function(){
it('prints values with then', function(done){
printValue(1)
.then(printValue(2))
.then(function(value){
console.log('then value: ', value);
})
.then(done())
});

it('prints values with return', function(done){
printValue(1)
.then(function(){
return printValue(2);
})
.then(function(value){
console.log('return value: ', value);
})
.then(done())
});

});


output:

1
2
then value: 1

1
2
return value: 2


why does the first test retain the value from the original promise, when the second test get the value from the second promise? Does this mean that using the
.then(async())
only works when you aren't passing arguments into the functions? or is there still a way to pass arguments using the above the syntax?

Answer

That's not easy to see.

In the first part, you have:

printValue(1)
      .then(printValue(2))
      .then(function(value){
         console.log('then value: ', value);
      })

You see, you are actually calling printValue(2) and it executes immediately when you call it, it doesn't wait for the previous functions to be called and their promises to be resolved. Although printValue returns a Promise, .then expects a function which returns a Promise when called (or just a function that returns a value).

So in .then(printValue(2)), .then receives a non-function value, it simply ignores it and goes to the next function in chain.

You can try this for example to see:

printValue(1)
    .then("hello!")
    .then(function (val) {
        console.log("got " + val)
    });

So, it is really the same as what you have, you just have a function that returns something, here we just replaced it with a value!

You can also try this:

var printValue = function (value){
    return new Promise(function(resolve, reject){
        console.log("called " , value)
        setTimeout(function () {
            console.log("resolving ", value);
            resolve(value)
        }, value*1000);
    });
}

You'll see here:

printValue(1)
        .then(printValue(2))
        .then(function (val) {
            console.log("got " + val)
        });

Both printValue(1) and printValue(2) are executed at the same time. After a second, the printValue(1) will resolve and got 1 will be printed.