1

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

;

3
  • 1
    You can do .then after an async function, as it returns a Promise once completed. The predicate inside then will be executed only once this function is completed. Commented Jan 18, 2018 at 20:30
  • Uh, you're not doing anything with the r promise? Commented Jan 18, 2018 at 20:37
  • @Bergi. Not sure if I should. I'm a bit confused with how promises and async work. Commented Jan 18, 2018 at 20:39

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

5 Comments

I was about to use this. But now I'm seeing the down votes. Why?
You don't need Promise.all for the sequential approach.
Not sure what I'm doing wrong here. I'm getting a "SyntaxError: Unexpected identifier" and its complaining about the Promise keyword. I installed "npm install promise --save" and also have "var Promise = require('promise');" in my js file. Am I missing something?
@MindGame what node version are you using? If you're using async, then Promise is surely available out of the box - you don't need any specific package
@OvidiuDolha I ran "node --version" and I got back v8.3.0. I was thinking the same thing that I should not need to install it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.