2

I'm using ES6 javascript promises in Chrome and am having trouble understanding why the promise executed within the function _getStatus() is not returning the result argument in the success handler which would result in the alert box containing "done". Instead, I get an alert box that says "undefined".

myNameSpace = function(){    
    var obj = {
        groupA: {
            status: "inactive"
        },
        groupB: {
            status: "active"
        }
    };

    function _getStatus(group){
        _finishTask().then(function(result){
            return result; // doesn't return anything
        });
    }

    function _finishTask(){
        var promise = new Promise(function(resolve, reject){            
            // do some task before resolving
            resolve("done");
        });
        return promise;
    };

    return{
        getStatus:_getStatus
    }
}();

$(function(){
    alert(myNameSpace.getStatus("groupA")); // why is this "undefined" instead of "done"?
});
Vee
  • 1,821
  • 3
  • 36
  • 60
  • Right, `getStatus` doesn't return anything. You may want to check http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call – elclanrs Apr 11 '15 at 07:06

2 Answers2

2

Because this is not how Promises work. You need to make sure both _getStatus and _finishTask return Promise objects. Then you will be able to use those promises API methods to execute subsequent code what promise is resolved.

So your code should look something like this:

myNameSpace = function() {
    var obj = {
        groupA: {
            status: "inactive"
        },
        groupB: {
            status: "active"
        }
    };

    function _getStatus(group) {
        return _finishTask().then(function(result) {
            return result + " and tested";
        });
    }

    function _finishTask() {
        return new Promise(function(resolve, reject) {
            // do some task before resolving
            resolve("done");
        });
    };

    return {
        getStatus: _getStatus
    }
}();

myNameSpace.getStatus("groupA").then(alert);

Finally, regarding this construction:

return _finishTask().then(function(result) {
    return result;
});

_finishTask returns a Promise object, when this promise is resolved you get into then callback. Whatever value you return from this callback becomes a new resolution value for the subsequent success callbacks down the resolution chain.

Demo: http://plnkr.co/edit/K1SWKuTYA3e46RxdzkCe?p=preview

dfsq
  • 191,768
  • 25
  • 236
  • 258
  • thanks the explanation. Just in case this helps somebody else, I found a helpful article - http://www.html5rocks.com/en/tutorials/es6/promises/). Here's a paragraph that improved my understanding how promises work (i.e. how _getStatus also returns a promise object even though only 1 was explicitly created in _finishTask): If you return a value, the next "then" is called with that value. However, if you return something promise-like (anything with a "then" method as promise-like), the next "then" waits on it, and is only called when that promise settles (succeeds/fails). – Vee Apr 11 '15 at 17:50
1

You cant return a result from an asynchronous function as the code running it has already finished by the time the response is returned.

You can however pass in a callback to execute once the code is complete:

function _getStatus(group, callback){
    _finishTask().then(function(result){
        callback(result);
    });
}


$(function(){
    myNameSpace.getStatus("groupA", function(result) {
        alert(result);
    });
});

or use the promise api itself (in this case your _getStatus method is a little redundant):

function _getStatus(group){
    return _finishTask();
}


$(function(){
    myNameSpace.getStatus("groupA").then(function(result) {
        alert(result);
    });
});
dannyshaw
  • 368
  • 2
  • 6
  • Thanks, @technix! Your first sentence captures my misunderstanding. I agree with what you wrote re: _getStatus being redundant in the example, but my code was simplified to make the question clearer. Because I need to include stuff in _getStatus, I thought @dfsq's solution was slightly more fleshed for me though your solution also helped me as well. Thanks! – Vee Apr 11 '15 at 07:47