This is similar to, but not quite the same as How do I access previous promise results in a .then() chain?
I have a situation where I am making two async requests in parallel, followed by a third async request which depends on the success of the first two, and finally passing the results of the second async request to the function callback.
As of now I understand how to do this in two ways (.catch statements and function signatures omitted for brevity):
Using scope closure (my current implementation)
var foo;
Promise.join(promiseA, promiseB, function(resultsA, resultsB) {
foo = resultsB;
return promiseC;
})
.then(function() {
// foo is accessible here
callback(null, foo);
});
Using Promise.bind, but have to use Promise.map instead of Promise.join
var targetIndex = 1;
Promise.resolve(promises)
.bind({})
.map(function(response, index) {
if (index === targetIndex) {
this.foo = response;
}
})
.then(function() {
return promiseC;
})
.then(function() {
// this.foo is accessible here
callback(null, this.foo);
});
As you can tell, option 2 is rather ugly since I have to manually check if the index parameter of the mapper matches the index of the promise result that I care about. Option 1 uses scope closure, which I understand is undesirable in most cases (but seems to be my best option at this point).
What I would really like to do is something like:
Promise.bind({})
.join(promiseA, promiseB, function(resultsA, resultsB) {
this.foo = resultsB;
return promiseC;
})
.then(function() {
// I WISH this.foo WAS ACCESSIBLE HERE!
callback(null, this.foo);
});
Is there a way for me to utilize Promise.join instead of Promise.map to avoid using a scope closure in this situation?
You have a interesting use case since a Promise needs the result of a promise multiple steps back in the chain. For such a "backward" problem, I would recommend a "backward" solution; adding resultB back into the chain after promiseC:
Promise.join(promiseA, promiseB, function(resultA, resultB) {
return promiseC.then(function() {
return resultB;
});
})
.then(function(resultB) {
callback(null, resultB);
});
Ideally, promiseC should result in resultB, but that's now always possible.
Edit: Note that I didn't used nested promises on purpose here. The anonymous function is there only to pass values, not execute logic. This approach does the same thing:
...
return promiseC.then(function() {
callback(null, resultB); // really not what you should be doing
});
but is discouraged because it added a layer of nested logic which ruins the design principle of chaining.
Edit 2: This can be achieved using bound closures like:
Promise.join(promiseA, promiseB).bind({})
.then(function(resultA, resultB) {
this.resultB = resultB;
return promiseC;
})
.then(function(resultC) {
callback(null, this.resultB);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With