在Promise中处理错误,就像async / await语法中的stream程一样
我有一些问题需要处理“平行”的多重拒绝。 当我们“并行等待”时如何处理asynchronous函数中的拒绝。
这里是一个例子:
function in_2_sec(number) { return new Promise((resolve, reject) => { setTimeout(() => { reject('Error ' + number); }, 2000); }) } async function f1() { try { let a = in_2_sec(3); let b = in_2_sec(30); return await a + await b; // awaiting in "parallel" } catch(err) { console.log('Error', err); return false; } } async function f2() { try { let a = await Promise.all([in_2_sec(3), in_2_sec(30)]); return a[0] + a[1]; } catch(err) { console.log('Error', err); return false; } } // f1().then(console.log) // UnhandledPromiseRejectionWarning // f2().then(console.log) // Nice
f1()
在节点中创build一个UnhandledPromiseRejectionWarning
,因为第二个拒绝(b)没有被处理。
f2()
完美的工作, Promise.all()
做的伎俩,但如何使用async / await语法,没有Promise.all()
?
f2()
完美的工作,Promise.all()
做的伎俩,但如何使用async / await语法,没有Promise.all()
?
一点也不。 使用Promise.all
! 这是它的目的。 不要想到async
/ await
replace诺言 – 你仍然在使用它,它只是语法糖, then
调用。 Promise.all
没有语法replace。
当然,也可以重新实现Promise.all
的行为(依赖于Promise
构造函数和.then
原语),但是你真的不想这么做(有太多的陷阱)。
我能想到的最简单的事情,我不喜欢它,就是无条件的调用来catch
错误path,可能带有效用函数。
有了这些实用function:
function noop() { } function markHandled(...promises) { promises.forEach(p => p && p.catch(noop)); }
它的:
async function f2() { let a, b; try { a = in_2_sec(3); b = in_2_sec(30); return await a + await b; } catch(err) { console.log('Error', err); markHandled(a, b); return false; } }
这样,我们明确地忽略了我们不在乎的拒绝,而是抓住了主要的错误。
例:
function in_2_sec(number) { return new Promise((resolve, reject) => { setTimeout(() => { reject('Error ' + number); }, 2000); }) } function noop() { } function markHandled(...promises) { promises.forEach(p => p && p.catch(noop)); } async function f2() { let a, b; try { a = in_2_sec(3); b = in_2_sec(30); return await a + await b; } catch(err) { console.log('Error', err); markHandled(a, b); return false; } } f2().then(console.log);