drm*_*wer 5 javascript async-await
考虑以下片段:
try {
const client = getClientThatMustBeClosed();
const data = await shortRunningOperation(client);
return Promise.resolve(data);
} catch (error) {
return Promise.reject(error);
} finally {
// any exception in the following function is caught and dealt with internally...
await longRunningOperation(client);
client.close();
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,我想在shortRunningOperation()完成后立即将数据返回给调用函数,而无需等待longRunningOperation()完成。但是关闭client必须等到longRunningOperation()完成后。
这个jsfiddle会建议返回语句等待finally块完成......在这种情况下,在不等待longRunningOperation()完成的情况下尽快将数据返回到调用函数的正确方法是什么?
下面是一些简单的测试代码,显示该finally块确实执行,即使在该try块返回之后也是如此。
function wait (ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
})
}
async function test () {
try {
await wait(1000);
console.log('try block complete');
return;
} catch (err) {
console.log('catch err:', err);
return;
} finally {
await wait(3000);
console.log('finally block complete');
}
}
test();Run Code Online (Sandbox Code Playgroud)
但正如OP所指出的,在finally块完成之前,try块的值不会被返回。
如果需要立即尝试返回值,请不要使用finally 块。相反,请将持续时间较长的清理代码放在 try 块中,但不要使用await.
function wait (ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
})
}
async function test () {
try {
await wait(1000);
console.log('try complete');
// put cleanup here without using await
wait(3000).then(() => {
console.log('cleanup complete');
});
return 'try return';
} catch (err) {
console.log('catch err:', err);
return err;
}
}
test().then(result => console.log('result:', result));Run Code Online (Sandbox Code Playgroud)
更新:您可以使用finally块而不阻止(延迟)try返回,但前提是该finally块不包含 areturn或await。
function wait(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function test() {
try {
await wait(1000);
console.log('try complete');
return 'try return';
} catch (err) {
console.log('catch err:', err);
return err;
} finally {
// cleanup without await
wait(3000).then(() => {
console.log('long duration cleanup complete');
});
// do not return here
}
}
test().then((result) => console.log('result:', result));Run Code Online (Sandbox Code Playgroud)