Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bluebird promise - then after finally

I encountered some issue in Bluebird/Promises. For the Promise1 everything works fine either if call fullfill or reject. However when we return Promise2 in a finally block it works only for reject and for fullfil we get undefined in then's callback.

function getPromise1() {
    return new Promise(function(fulfill, reject) {
        fulfill("OK1");
    });
}

function getPromise2() {
    return new Promise(function(fulfill, reject) {
        fulfill("OK2");
    });
}


getPromise1()
    .then(function(c){
        console.log(c);
    })
    .catch(function(e) {
        console.log(e);
    })
    .finally(function() {
        return getPromise2();
    })
    .then(function(c){
        console.log(c);
    })
    .catch(function(e) {
        console.log(e);
    });

Output:

OK1

undefined

like image 518
Suprido Avatar asked Jun 29 '15 09:06

Suprido


Video Answer


2 Answers

The finally block does not change the return value.

There are special semantics for .finally() in that the final value cannot be modified from the handler.

Bluebird will wait for it, but it will not change the return value (this is an opinionated choice and aligns with the proposed ECMAScript standard semantics - like finally in some languages and unlike others).

like image 134
Benjamin Gruenbaum Avatar answered Oct 05 '22 10:10

Benjamin Gruenbaum


If you want to chain a handler irrespective of the previous promise's outcome, you can use .reflect() to convert the result to a PromiseInspection.

The official documentation is here, although it doesn't really make this use-case very clear at the time of this writing.

Better example:

Promise.resolve("OK1")
    .then(function(x) {
        console.log(x); // outputs OK1
        return Promise.reject("Rejection demo");
    })
    .reflect()
    .then(function(settled) {
        if (settled.isRejected()) {
            // outputs Rejected: Rejection demo
            console.log("Rejected:", settled.reason());
        }
        if (settled.isFulfilled()) {
            console.log("Fulfilled:", settled.value()); // skipped
        }
        return Promise.resolve("OK2");
    })
    .then(function(c){
        console.log(c);  // outputs OK2
    });
like image 32
steamer25 Avatar answered Oct 05 '22 10:10

steamer25