Reputation: 7606
At the risk of sounding stupid: What's the most efficient way to wait for one promise to settle? Say I have promise A and I want to create promise B. The fulfillment of B does not depend on the final value of A. It should proceed even if A is rejected. The process shouldn't start, however, until A is settled one way or the other.
What I have currently looks like the following:
var prevResult;
function doStuff() {
if (prevResult) {
prevResult = promise.settle([ prevResult ]).then(function() {
return doStuff();
})
} else {
prevResult = updateDB().finally(function() {
prevResult = null;
});
}
return prevResult;
}
The code is a bit non-obvious. I'm also a bit worried about chaining a bunch of promises from settle() together, seeing how it's function for performing less trivial kind of coordination. Seems like there ought to be a simpler way of doing this.
Upvotes: 2
Views: 6541
Reputation: 276306
Recently, .reflect
was introduced as a more flexible .settle
and a better abstraction altogether. Your use case sounds like something that's easy to do with .reflect
A.reflect().then(function(){
return doSomethingThatReturnsB();
});
A full example with your code:
var prevResult;
function doStuff() {
prevResult = Promise.resolve(prevResult).reflect().then(function(){
return updateDB();
});
return prevResult;
}
Upvotes: 3
Reputation: 664548
I think the best way would be to put doStuff
as both fulfillment and rejection handler:
prevResult = prevResult.then(function() { return doStuff(); },
function() { return doStuff(); });
Or alternatively
prevResult = prevResult.catch(ignore).then(function() { return doStuff(); });
It seems you are trying to queue updateDB
operations. I would recommend not to reset prevResult
to null
, but instead just make it a promise that is fulfilled when all queued operations are done. Have a look at this example.
Upvotes: 0
Reputation: 19288
Let's assume you have two promise-returning functions doAsync_A
and doAsync_B
.
The following expression will execute doAsync_A
, wait for its promise to settle (to become fulfilled or rejected), then execute doAsync_B
Promise.settle([doAsync_A()]).then(doAsync_B);
doAsync_B
will be passed a "PromiseInspection" array (here a single element). If necessary, you can test whether doAsync_A
was successful or failed.
function doAsync_B(results) {
var r = results[0];
if (r.isFulfilled()) { // check if was successful
console.log(r.value()); // the promise's return value
} else if (r.isRejected()) { // check if the read failed
console.log(r.reason()); // the promise's rejection reason
}
}
adapted from the bluebird documentation
Upvotes: 0
Reputation: 8021
You can use finally, which fires regardless of the outcome of the previous promise.
Following code is from the bluebird github doco.
function ajaxGetAsync(url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest;
xhr.addEventListener("error", reject);
xhr.addEventListener("load", resolve);
xhr.open("GET", url);
xhr.send(null);
}).finally(function() {
$("#ajax-loader-animation").hide();
});
}
Upvotes: 0