简体   繁体   中英

Does a return statement in the try block wait for an await statement in the finally block?

Consider the following snippet:

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();
}

Ideally I want to return data to the calling function right after shortRunningOperation() completes, without waiting for longRunningOperation() to complete. But closing the client must wait until after longRunningOperation() completes.

This jsfiddle would suggest that the return statement waits for the finally block to complete... in which case, what is the correct way to get data back to the calling function ASAP without waiting for longRunningOperation() to complete?

Here's some simple test code that shows that the finally block does execute, even after the try block returns.

 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();

But as the OP notes, the try block value will not be returned until the finally block is completed.

If the try return value is wanted immediately, don't use a finally block. Instead, put the long duration cleanup code in the try block, but don't use the 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));

Update: You can use a finally block without blocking (delaying) the try return, but only if the finally block does not contain a return or 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));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM