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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With