Home > database >  wait for promise before exit process
wait for promise before exit process

Time:04-10

I'm trying to run a NodeJS code that reads some data fields from an array, use them to do a database query to check if the data is duplicate before inserting them into the corresponding table.

My NodeJS code will be called from a PHP script so I need to know when it ends this is why I need to add process.exit(0) somewhere. The problem I have is that if I add it, the script is terminated and my promise never gets the time to send back the result.

Here is my code:

var bar = new Promise((resolve, reject) => {
        result.forEach((row, index, array) => {
            var escaped = _.map(row, mysql.escape);
            var checkQuery = "SELECT COUNT(*) as found FROM data WHERE field1 = "   escaped[0]   " AND field2 = "   escaped[1]   " AND field3 = "   escaped[2]   " AND field4 = "   escaped[3]   " AND field5 = "   escaped[4]   " AND field6 = "   escaped[5]   " AND field7  = "   escaped[6]   ";";
            conn.query(checkQuery, function (err, res) {
                if (err) {
                    console.log("Error checking row for duplicate");
                    console.log(checkQuery);
                    process.exit(1);
                } else {
                    if (res[0].found == 0) {
                        var query = " (";
                        var escaped = _.map(row, mysql.escape);
                        var csv = escaped.join(',');
                        query  = csv;
                        query  = ")";
                        query  = row !== _.last(result) ? ',' : ';';
                        console.log(query);//This will change to inserting the data to the table
                    }else{
                        console.log("Duplicate found!");
                    }
                }
            });
            if (index === array.length -1) resolve();
        });
    });

    bar.then(() => {
        console.log('All done!');
        process.exit(0);
    });

If I remove process.exit(0); I see "All done" first then console.log(query) result. If I add it, the script is terminated and I see "All done" only.

Is there a better approach to do this task please?

Thanks.

CodePudding user response:

Use Reject/Resolve to manage promise in Nodejs

When your task fulfils your request send result with resolve(); and if its failing use reject();

In your case you are not managing promise properly that's why it's running asynchronously, better to use following way with the proper returns.

var bar = new Promise((resolve, reject) => {
    return result.forEach((row, index, array) => {
        var escaped = _.map(row, mysql.escape);
        var checkQuery = "SELECT COUNT(*) as found FROM data WHERE field1 = "   escaped[0]   " AND field2 = "   escaped[1]   " AND field3 = "   escaped[2]   " AND field4 = "   escaped[3]   " AND field5 = "   escaped[4]   " AND field6 = "   escaped[5]   " AND field7  = "   escaped[6]   ";";
        return conn.query(checkQuery, function (err, res) {
            if (err) {
                console.log("Error checking row for duplicate");
                console.log(checkQuery);
                return reject(err);
            } else {
                if (res[0].found == 0) {
                    var query = " (";
                    var escaped = _.map(row, mysql.escape);
                    var csv = escaped.join(',');
                    query  = csv;
                    query  = ")";
                    query  = row !== _.last(result) ? ',' : ';';
                    console.log(query);//This will change to inserting the data to the table
                    return resolve(query)
                } else {
                    console.log("Duplicate found!");
                    return reject('Duplicate Found');
                }
            }
        });
    });
});

bar.then((data) => {
    console.log('All done!');
});

In above code I am returning query resolve/reject so it makes better to run in more synchronised way. return conn.query(checkQuery, function (err, res) {

Plus, while processing this promise I am handling with .then((data) so I can handle that resolve values here.

bar.then((data) => {
    console.log('All done!');
});

Note: If you are rejecting any promise it won't be available in above .then block you'll find this reject in catch block so code will be changed in following way.

bar.then((data) => {
    console.log('All done!');
}).catch(err=>{
    console.log(err);
});

CodePudding user response:

You can try the following:


(async () => {

    await new Promise((resolve, reject) => {
        result.forEach((row, index, array) => {
            var escaped = _.map(row, mysql.escape);
            var checkQuery = "SELECT COUNT(*) as found FROM data WHERE field1 = 
    "   escaped[0]   " AND field2 = "   escaped[1]   " AND field3 = "   
escaped[2]   " AND field4 = "   escaped[3]   " AND field5 = "   escaped[4]   " AND field6 = "   escaped[5]   " AND field7  = "   escaped[6]   ";";
            conn.query(checkQuery, function (err, res) {
                if (err) {
                    console.log("Error checking row for duplicate");
                    console.log(checkQuery);
                    process.exit(1);
                } else {
                    if (res[0].found == 0) {
                        var query = " (";
                        var escaped = _.map(row, mysql.escape);
                        var csv = escaped.join(',');
                        query  = csv;
                        query  = ")";
                        query  = row !== _.last(result) ? ',' : ';';
                        console.log(query);//This will change to inserting the data to the table
                    }else{
                        console.log("Duplicate found!");
                    }
                }
            });
            if (index === array.length -1) resolve();
        });
    });


        console.log('All done!');

})();

You don't even need to call the process.exit(0) because the code will always terminate when the job is done :)

  • Related