Promise doesn't resolve the right value

63 views Asked by At
function retRGObj(objName, xTime) {
    return new Promise(
        function (resolve, reject) {
            let data = {}
            findR(objName, xTime).then(function (msg) {
                data.R = msg
                console.log(data) //--> saves the expected value
            }).then(findG(objName, xTime).then(function (msg) {
                data.G = msg
                console.log(data) //--> saves the expected value
            }))
            console.log(data) //--> all values are gone, returned value is "Object {}"
            resolve(data)
        })
}

I don't know how I can not return the final value, it gets emptied in the last scope. How/why is it?

1

There are 1 answers

8
T.J. Crowder On BEST ANSWER

Presumably, findR and findG work asynchronously; otherwise, it would be weird that they return promises. So what you need to do is resolve your promise only when those promises complete. In your case, that would be within the callback to findG(...).then. Also, what you're passing into findR(...).then (the return value of findG) is highly suspect.

Here's a swing at it, but of course it depends on the details:

// If they have to be nested (one after another)
function retRGObj(objName, xTime) {
    return findR(objName, xTime).then((R) => {
        return findG(objName, xTime).then((G) => {
            return {R, G};
        });
    });
}

Or we can condense it further, because if an arrow function has just one expression in it and no {} around it, the result of that expression is its return value. So (not for the faint of heart!):

function retRGObj(objName, xTime) {
    return findR(objName, xTime).then(
        (R) => findG(objName, xTime).then(
            (G) => ({R, G})    // Note: The () around {R, G} matter
        )
    );
}

That waits for findR to finish before starting findG; I don't immediately see why that would be necessary, as I don't see anything in the call to findG that relies on the results from findR.

If they can be in parallel, then updating my earlier version based on Bergi's comment, you can do this:

function retRGObj(objName, xTime) {
    return Promise.all(
        [findR(objName, xTime), findG(objName, xTime)]
    ).then(([R, G]) => {
         return {R, G};
    });
}

Or condensed:

function retRGObj(objName, xTime) {
    return Promise.all(
        [findR(objName, xTime), findG(objName, xTime)]
    ).then(([R, G]) => ({R, G}));
}