1

I'm new to promise. I am trying to use promise to send queries to mysql db. After some queries I will use the result from the query, do some calculations and then use the output as some parameters of next query. Looks like the following:

firstQuery(). then(secondQuery). then(thirdQuery). then(fourthQuery). ...

Say, in the fourthQuery, I need to use results coming from firstQuery and secondQuery, and will have some additional calculations. How should I do that?

I know I can get the result from the previous promise by passing a parameter to the function:

then(thirdQuery). then(cal("I can only get output from thirdQuery here")). then(fourthQuery("pass output from cal"))

In this case, I don't any advantages of Promise over callbacks, because I can always write a function to simplify the repeated callbacks.

Pano
  • 2,099
  • 6
  • 16
  • 24

3 Answers3

0

In that quite common cases you can move results of each then outside promise, and then they will be accessible in the remaining then blocks.

For example:

function first() { ... }
function second() { ... }
function third() { ... }
function fourth(firstValue, secondValue) { ... }

var firstResponse, secondResponse;
first()
.then(function(_firstResponse) {
  firstResponse = _firstResponse;
  return second();
})
.then(function(_secondResponse) {
  secondResponse = _secondResponse;
  return third();
})
.then(function() {
  return fourth(firstResponse, secondResponse);
})
Krzysztof Sztompka
  • 7,066
  • 4
  • 33
  • 48
0

If you can rewrite firstQuery, secondQuery etc you can do something like this

function firstQuery(allResult = {}) {
    return doTheQuery()
    .then(result => {
        allResult.first = result;
        return result;
    });
}
function secondQuery(allResult = {}) {
    return doTheQuery()
    .then(result => {
        allResult.second = result;
        return result;
    });
}
function thirdQuery(allResult = {}) {
    return doTheQuery()
    .then(result => {
        allResult.third = result;
        return result;
    });
}
function fourthQuery(allResult = {}) {
    return doTheQuery(allRessult.first, allResult.second)
    .then(result => {
        allResult.fourth = result;
        return result;
    });
}

then you can write use

firstQuery()
.then(secondQuery)
.then(thirdQuery)
.then(fourthQuery)
.then ...

the final result will be an object with the values of all the queries in {first, second, third, fourth} properties

Of course, if you want just the fourth query result

firstQuery()
.then(secondQuery)
.then(thirdQuery)
.then(fourthQuery)
.then(result => result.fourth)
.then ...
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
0

Usually you should think of promises as values and dependencies rather than a way to control the execution flow. One solid option is organizing your code something like this:

var firstResult = firstQuery();
var secondResult = firstResult.then(secondQuery);
var thirdResult = secondResult.then(thirdQuery);
var fourthResult = Promise.join(firstResult, secondResult, fourthQuery);

Basically I guess the key here is knowing of the join method of the bluebird library (others exist that could be used for the same effect), but an additional benefit is I find this kind of code much less error prone than one mixing raw variables and promise-variables.

Also note that this is possible because it's totally fine to call then on the same promise multiple times.

DonSteep
  • 1,075
  • 10
  • 10
  • 1
    Reading [Promise.join documentation](http://bluebirdjs.com/docs/api/promise.join.html), isn't it actually `var fourthResult = Promise.join(firstResult, secondResult, fourthQuery);` – Jaromanda X Dec 16 '16 at 23:30
  • Jaromanda you're right. This appears to have changed.. the documentation says this form still works but is deprecated. – DonSteep Dec 16 '16 at 23:32
  • `is still supported partially` - the partially isn't exactly qualified :p – Jaromanda X Dec 16 '16 at 23:33
  • Well worked for me last time I used it :) Anyhow I updated the answer, thanks for the heads up! – DonSteep Dec 16 '16 at 23:34