0
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?

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
CRQ
  • 357
  • 2
  • 4
  • 14
  • Just don't use the [promise constructor antipattern](http://stackoverflow.com/q/23803743/1048572). – Bergi Jun 09 '15 at 18:20
  • 1
    Also, you must pass a callback to `.then()`, not that `findG(…).then(…)` promise – Bergi Jun 09 '15 at 18:21
  • Just for the reference, you're looking for `return Promise.all([findR(objName, xTime), findG(objName, xTime)]).then(function([msg1, msg2]) { let data = {R:msg1, G:msg2}; console.log(data); return data; })` – Bergi Jun 09 '15 at 18:23
  • @Bergi Oh man thanks for this antipattern link as its educating, I didn't know about it and I am new to promises. – CRQ Jun 09 '15 at 18:25

1 Answers1

1

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}));
}
Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thank you, this works as I expected now, I am really new to promises and it seems I code it ugly and bad, yeah findG doesn't need anything from findR, I just couldn't be sure how to code it without a problem so I just chained it. – CRQ Jun 09 '15 at 18:27
  • How to rewrite this without using arrow function expression; then(([R, G]) => { return {R, G}; }) – CRQ Jun 09 '15 at 18:46
  • @Mehmet: Why do you not want arrow functions? – T.J. Crowder Jun 09 '15 at 18:47
  • I am using nwjs, and "Uncaught SyntaxError: Unexpected token =>" but please keep the arrow function answer as it will be good for the records. – CRQ Jun 09 '15 at 18:49
  • @Mehmet: You might want to switch to [Babel](https://babeljs.io) transpilation. But to remove the arrow functions from the un-condensed versions above, just put the word `function` in front of the arguments and remove the `=>`. So `(R) => { return {R, G}; }` becomes `function(R) { return {R, G}; }` (to switch over the condensed versions, you need to add the {} around the body as well). – T.J. Crowder Jun 09 '15 at 18:50
  • @T.J.Crowder Oh that's very nice, I'll take a look thank you for sharing. – CRQ Jun 09 '15 at 18:52
  • @T.J.Crowder Just a quick question tho, how would you normally write (([R, G]) => without arrow, because when I write function([R,G]) { return {R, G}; } then I get: Uncaught SyntaxError: Unexpected token [ – CRQ Jun 09 '15 at 18:56
  • 1
    @Mehmet: That means that it doesn't handle "spread arguments," either, which are another feature of ES6 (not just arrow functions). So you'd have to use `function(result) { return {R: result[0], G: result[1]}`. I don't think I'd recommend continuing to use something with such dramatically spotty support for ES6 syntax. :-) – T.J. Crowder Jun 09 '15 at 20:04