超时在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策略会给我们分配太多的对象,以至于其他的策略需要,但这是无关紧要的。