Reputation: 1251
I'm a bit confused on how to make my nodejs exit after it completes. I know what the syntax is to exit the nodejs script. But I'm having a hard time figuring out how this whole async syntax really works. So what I want to do is call process.exit() after my nodejs application has completed everything. Right now when I put it in certain places it exits the script before the script has completed.
Here is my code where I'm getting emails from the server and writing them to the database.
(async function () {
try {
let pool = await sql.connect(config)
//Query the database
let emails = await pool.request()
.query('select uid from email')
emails.forEach(function(email) {
const request = pool.request();
request.input('uid', sql.VarChar, email.id);
request.input('mail_address', sql.VarChar, email.mailAddress);
request.input('mail_address_display_name', sql.VarChar, mail.displayName);
request.input('subject', sql.VarChar, mail.subject);
request.input('body', sql.VarChar, mail.body);
request.input('sent_date', sql.DateTime, mail.sentDate);
request.input('created_by', sql.VarChar, mail.CreatedBy);
var saveEmail = async function() {
let result = await request.query('INSERT INTO email_copy(uid, mail_address, mail_address_display_name, subject, body, sent_date, created_by) OUTPUT INSERTED.Email_ID values (@uid, @mail_address, @mail_address_display_name, @subject, @body, @sent_date, @created_by)', (err, result) => {
var emailId = result.recordset[0].Email_ID;
return result;
})
}
var r = saveEmail();
});
}
} catch (err) {
console.log(err);
// ... error checks
}
})()
.then((result) =>{
process.exit()
});
;
Upvotes: 1
Views: 65
Reputation: 5413
Looks like emails.forEach(..
will instantly execute whatever you define inside.
Even if you define an async function like your saveEmail
, the forEach
will start execution of saveEmail
for each email at the same time.
So you cannot easily know when everything has finished.
A simple way to do that would be:
await Promise.all(emails.map(function(email) {
...
return saveEmail();
})).then(() => process.exit());
This creates a Promise that waits for ALL the promises inside an array to finish. These promises in this case are actually all the saveEmail
for each email (using map
to map each email string to a Promise for executing save in this case).
BTW: saveEmail
returns a Promise because it's defined async
.
NOTE: this still executes saveEmail simultaneously for all emails, but now you have a controlled way to intercept when all these save are done.
You could also implement a sequential approach as such:
await emails.reduce(function(promise, email) {
...
return promise.then(() => saveEmail());
}, Promise.resolve()).then(() => process.exit());
This works by chaining all saveEmail promises in a chain starting with an empty promise (Promise.resolve()
) and each save will wait for the previous one before executing.
Upvotes: 1