I recently had a problem where I needed to send an email to a customer after they placed an order. The process was to await the database creation of the order and if successful send an email confirmation message. While I could have separated this into two functions, I needed to use-server and I am using typescript, which also makes passing the order data to the send Email function problematic.
Therefore, my implementation was to have a function create an order and then call the send email function with the order, before returning to the client. This made creating orders a slow process. I opted to change this since sending an email is not of immediate need that getting the response on whether the order has been created succesfully.
In JavaScript, the return
statement immediately terminates the execution of a function. However, there are situations where you might want to perform additional actions after the return
statement has been encountered, even though it seems counterintuitive. This is generally achieved through asynchronous operations or using specific mechanisms like try...catch...finally
blocks.
I found three methods to achieve this.
Method 1: try...catch...finally
The finally
block of a try...catch
statement always executes, regardless of whether an exception is thrown or not. This provides a reliable way to execute code after a return
statement within the try
block.
This has its limitations since we only want to send the email after the order creation has been successful. We can counter this by using a variable to track whether the function has thrown an error before sending the email, but this is not a good practice.
One problem I faced with this setup is that sendEmail
relies on the returned order object data from the try block and passing it around became problematic.
Method 2: setImmediate()
setImmediate()
(available in Node.js and some browser environments) schedules a callback function to be executed after the current event loop iteration completes. This ensures that the callback runs after the function containing the return
statement has finished its synchronous execution.
Method 3: setTimeout()
Similar to setImmediate()
, setTimeout()
Schedules a callback function to be executed after a specified delay (in milliseconds). While introducing a small delay, it offers a more widely compatible approach for browsers and Node.js.
Important Note: The order of execution in the setImmediate()
and setTimeout()
examples might seem unexpected at first. The key is understanding that the return
statement concludes the synchronous part of the function. The callbacks scheduled by setImmediate()
or setTimeout()
are executed asynchronously, later in the event loop.
In conclusion, I found the
setImmediate()
implementation to be a lot faster in execution as it helps return the function return statement very early before the other logic is executed. However, it needs to be wrapped in a self-invoking async function.
How to Execute Something else after the Return Statement in Javascript
By Tech Wizard published on Jan 19, 2025
I recently had a problem where I needed to send an email to a customer after they placed an order. The process was to await the database creation of the order and if successful send an email confirmation message. While I could have separated this into two functions, I needed to use-server and I am using typescript, which also makes passing the order data to the send Email function problematic.
Therefore, my implementation was to have a function create an order and then call the send email function with the order, before returning to the client. This made creating orders a slow process. I opted to change this since sending an email is not of immediate need that getting the response on whether the order has been created succesfully.
In JavaScript, the return
statement immediately terminates the execution of a function. However, there are situations where you might want to perform additional actions after the return
statement has been encountered, even though it seems counterintuitive. This is generally achieved through asynchronous operations or using specific mechanisms like try...catch...finally
blocks.
I found three methods to achieve this.
Method 1: try...catch...finally
The finally
block of a try...catch
statement always executes, regardless of whether an exception is thrown or not. This provides a reliable way to execute code after a return
statement within the try
block.
function myFunction() {
try {
return "Value from try block";
} catch (error) {
console.error("Error:", error);
} finally {
console.log("This always executes after the return statement.");
}
}
console.log(myFunction());
// Output: "Value from try block",
// Followed by
//"This always executes after the return statement."
This has its limitations since we only want to send the email after the order creation has been successful. We can counter this by using a variable to track whether the function has thrown an error before sending the email, but this is not a good practice.
function createOrder() {
let isError= false
try {
const order = await db.create()
return order
} catch (error) {
console.error("Error:", error);
isError = true
throw new Error(error)
} finally {
if (!isError) {
await sendEmail()
}
}
}
One problem I faced with this setup is that sendEmail
relies on the returned order object data from the try block and passing it around became problematic.
Method 2: setImmediate()
setImmediate()
(available in Node.js and some browser environments) schedules a callback function to be executed after the current event loop iteration completes. This ensures that the callback runs after the function containing the return
statement has finished its synchronous execution.
function myFunction() {
setImmediate(() => {
console.log("This executes after the return statement.");
});
return "Value from myFunction";
}
console.log(myFunction());
// Output: "Value from myFunction",
//"This executes after the return statement."
Method 3: setTimeout()
Similar to setImmediate()
, setTimeout()
Schedules a callback function to be executed after a specified delay (in milliseconds). While introducing a small delay, it offers a more widely compatible approach for browsers and Node.js.
function myFunction() {
setTimeout(() => {
console.log("This executes after the return statement (with a delay).");
}, 0); // 0 milliseconds delay
return "Value from myFunction";
}
console.log(myFunction());
// Output: "Value from myFunction",
//"This executes after the return statement (with a delay)."
Important Note: The order of execution in the setImmediate()
and setTimeout()
examples might seem unexpected at first. The key is understanding that the return
statement concludes the synchronous part of the function. The callbacks scheduled by setImmediate()
or setTimeout()
are executed asynchronously, later in the event loop.
In conclusion, I found the
setImmediate()
implementation to be a lot faster in execution as it helps return the function return statement very early before the other logic is executed. However, it needs to be wrapped in a self-invoking async function.