超时在asynchronous/等待
我与Node.js和TypeScript,我正在使用async/await
。 这是我的testing用例:
async function doSomethingInSeries() { const res1 = await callApi(); const res2 = await persistInDB(res1); const res3 = await doHeavyComputation(res1); return 'simle'; }
我想为整体function设置一个超时时间。 即如果res1
需要2秒, res2
需要0.5秒, res3
需要5秒我想有一个超时,3秒后,让我抛出一个错误。
使用正常的setTimeout
调用是一个问题,因为范围已经丢失:
async function doSomethingInSeries() { const timerId = setTimeout(function() { throw new Error('timeout'); }); const res1 = await callApi(); const res2 = await persistInDB(res1); const res3 = await doHeavyComputation(res1); clearTimeout(timerId); return 'simle'; }
而我无法用普通的Promise.catch
抓住它:
doSomethingInSeries().catch(function(err) { // errors in res1, res2, res3 will be catched here // but the setTimeout thing is not!! });
任何想法如何解决?
你可以使用Promise.race
来超时:
Promise.race([ doSomethingInSeries(), new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), 11.5e3)) ]).catch(function(err) { // errors in res1, res2, res3 and the timeout will be caught here })
你不能使用setTimeout
而不把它包装在承诺中。
好吧,我发现这样的方式:
async function _doSomethingInSeries() { const res1 = await callApi(); const res2 = await persistInDB(res1); const res3 = await doHeavyComputation(res1); return 'simle'; } async function doSomethingInSeries(): Promise<any> { let timeoutId; const delay = new Promise(function(resolve, reject){ timeoutId = setTimeout(function(){ reject(new Error('timeout')); }, 1000); }); // overall timeout return Promise.race([delay, _doSomethingInSeries()]) .then( (res) => { clearTimeout(timeoutId); return res; }); }
任何错误?
对我来说有点味道的是,使用承诺作为asynchronous策略会给我们分配太多的对象,以至于其他的策略需要,但这是无关紧要的。