Promise.try()
Update 2017-08-12: I added an FAQ.
The proposal “Promise.try()
” by Jordan Harband is currently at stage 1. This blog post explains how it works.
Promise.try()
To understand what Promise.try()
does, consider the following code:
function countPlusOneAsync() {
return countAsync()
.then(result => {
return result + 1;
});
}
If countAsync()
throws a synchronous exception then so does countPlusOneAsync()
. But we want the latter function to deliver all errors via Promises. To avoid this problem, we can use Promise.try()
:
function countPlusOneAsync() {
return Promise.try(() => { // (A)
return countAsync(); // (B)
})
.then(result => {
return result + 1;
});
}
Now errors thrown in line B will lead to the rejection of the Promise returned in line A. Promise.try()
has two additional benefits:
countAsync()
, it will be converted to an instance of Promise
.Until we get Promise.try()
, we can use the following work-around:
function countPlusOneAsync() {
return Promise.resolve().then(() => { // (A)
return countAsync();
})
.then(result => {
return result + 1;
});
}
Promise.resolve()
creates a Promise that is fulfilled with undefined
. That result does not matter to us. What does matter is that we have just started a Promise chain and can put the code to try into the callback starting in line A.
Another work-around is to use the Promise
constructor:
function countPlusOneAsync() {
return new Promise(resolve => {
resolve(countAsync());
})
.then(result => {
return result + 1;
});
}
If you can use async functions, they are the better choice and automatically convert all exceptions thrown inside their bodies to rejections. Alas, sometimes you need to work with Promises directly and then Promise.try()
is useful.
new Promise(···)
? Promise.try()
is relatively small syntactic sugar and easy to polyfill. Compared to using the Promise
constructor, it has the following advantages:
.then()
callbacks and can be moved more easily.Promise.prototype.finally()