场景
实际开发中,经常遇到一种情况:不知道或者不想区分,函数f是同步函数还是异步操作,但是想用 Promise
来处理它。因为这样就可以不管f是否包含异步操作,都用then
方法指定下一步流程,用catch
方法处理f抛出的错误。一般就会采用下面的写法。
Promise.resolve().then(f)
上面的写法有一个缺点,就是如果f是同步函数,那么它会在本轮事件循环的末尾执行。
const f = () => console.log('now');
Promise.resolve().then(f);
console.log('next');
// next
// now
上面代码中,函数f是同步的,但是用 Promise
包装了以后,就变成异步执行了。
那么有没有一种方法,让同步函数同步执行,异步函数异步执行,并且让它们具有统一的 API 呢?回答是可以的,并且还有两种写法。
匿名函数立即执行
const f = () => console.log('now');
(
() => new Promise(
resolve => resolve(f())
)
)();
console.log('next');
// now
// next
上面代码也是使用立即执行的匿名函数,执行new Promise()
。这种情况下,同步函数也是同步执行的。
Promise.try
鉴于这是一个很常见的需求,所以现在有一个提案,提供Promise.try
方法替代上面的写法。
const f = () => console.log('now');
Promise.try(f);
console.log('next');
// now
// next
事实上,Promise.try
存在已久,Promise
库Bluebird、Q和when,早就提供了这个方法。
由于Promise.try为所有操作提供了统一的处理机制,所以如果想用then方法管理流程,最好都用Promise.try包装一下。这样有许多好处,其中一点就是可以更好地管理异常。
Promise.try(() => do...
.then(...)
.catch(...)