javascriptnode.jsasynchronouspromiseq

How to get resolved value/rejected error in finally block?


Using the Q.js Javascript promise library, how can I get the resolved value/rejected error object in the finally block. Basically I want to execute common code in the finally block with the resolved data which was passed to the then block.

var q = require('Q');

var defer = q.defer();

setTimeout(function () {
    console.log("----------------------------------");

    promise2 = defer.promise;
    var t = promise2.then(function (value) {
        console.log('defer then => ' + value);
    })
    .catch(function (err) {
        console.log('defer catch => ' + err);
    })
    .finally(function (data) {
        console.log('function pro1 : ' + defer);
        // console.log('defer finally(resolved value) => ' + data); // how to get 123 here
        // console.log('defer finally(error) => ' + data); // how to get 'Error occurred.' here
        doSomething(data);
    })

    setTimeout(function () {
        console.log('after2: ' + t);
    },2000)

    defer.resolve('123');
    defer.reject('Error occurred.');
},10);


Solution

  • The finally is a function used to execute code regardless of the resolution or rejection of a promise, code such as cleaning resources (closing connections, etc). So it is not a good idea to use it for a case where you need the data. Also, I don't suggest the use of global variable, since this does not follow much the idea of the Promise.

    If you need both the value in case the Promise succeed or fails, I suggest using a sequence of then, catch and then, like this:

    var q = require('Q');
    
    var defer = q.defer();
    
    setTimeout(function () {
        console.log("----------------------------------");
    
        promise2 = defer.promise;
        var t = promise2.then(function (value) {
            console.log('defer then => ' + value);
            return { status: "success", value: value };
        })
        .catch(function (err) {
            console.log('defer catch => ' + err);
            return { status: "err", value: err };
        })
        .then(function (dataOrError) {
            console.log('function pro1 : ' + defer);
            // console.log('defer finally(resolved value) => ' + data); // how to get 123 here
            // console.log('defer finally(error) => ' + data); // how to get 'Error occurred.' here
            doSomething(dataOrError); // Here you can check if you got an error or the value you exepected.
        })
    
        setTimeout(function () {
            console.log('after2: ' + t);
        },2000)
    
        defer.resolve('123');
        defer.reject('Error occurred.');
    },10);
    

    But, if you are going to execute code, depending on the result of you promise (resolved or rejected), you should use this pattern:

    promise.then((data) => {
       //doSomething with data
       return data;
     }).catch((err) => {
       //doSomithing with error
       return error;
     }).then((dataOrError) => {
      //doSomething with dataOrErro that does not depend if it is data or error
     });