在退出进程之前等待承诺
我正在尝试运行一个nodejs代码,该代码从数组中读取一些数据字段,请使用它们进行数据库查询以检查数据是否在将数据插入到相应的表格中。
我的nodejs代码将从PHP脚本调用,因此我需要知道它何时结束,这就是为什么我需要在某个地方添加process.exit(0)。我的问题是,如果添加它,脚本将终止,我的承诺永远没有时间发送结果。
这是我的代码:
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);
});
如果我删除process.exit(0);
我看到“全部完成” 首先,然后console.log(query)
>结果。 如果添加它,脚本将终止,我看到“全部完成” 。
请问有更好的方法来完成这项任务吗?
谢谢。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是一种在应用程序退出之前等待承诺的方法。
Here is a way to wait for a promise before the application exits.
如果您对所有单独的异步操作使用 Promise,而不是尝试跟踪使用普通回调的异步操作,则在循环中运行多个异步操作并跟踪一切完成时间会变得非常非常容易。
你没有确切地说你的数据库是什么,但如果它是 mysql,那么就有一个 mysql2/promise 驱动程序本身支持承诺,这将是我建议切换到该驱动程序。然后你可以直接使用从
.query()
返回的promise。但是,在没有有关特定数据库驱动程序的信息的情况下,我展示了如何手动 promisify.query()
。然后,循环代码可以使用
for
循环和await
对数据库调用进行排序,以便很容易知道它们何时完成。该代码似乎试图在循环内构建一个查询,其中循环的每次迭代都会添加到下一次迭代(这就是
_.last(result) ? ',' : ';';
无论如何看起来都像)。如果是这种情况,则必须将查询变量移到循环之外,以便它可以从循环的一次迭代构建到下一次迭代。但是,您没有显示您真正想对该查询执行什么操作,因此您只能自己完成该部分。Running multiple asynchronous operations in a loop and tracking when everything is done is just way, way, way easier if you use promises for all the individual asynchronous operation rather than trying to track asynchronous operations that use plain callbacks.
You don't say exactly what your database is, but if it's mysql, then there is a
mysql2/promise
driver that natively supports promises and that would be my recommendation to switch to that. Then you can directly use a promise returned from.query()
. But, without the info about your specific database driver, I've shown how to manually promisify.query()
.Then, the looping code can use a
for
loop andawait
to sequence the database calls so it's easy to know when they are all complete.The code appears to be trying to build a query inside the loop where each iteration of the loop will add-on to the next (that's what
_.last(result) ? ',' : ';';
look like anyway). If that's the case, then the query variable has to be moved outside the loop so it can build from one iteration of the loop to the next. But, you don't show what you're really trying to do with that query so you're on your own for that part.您可以决定将有多少诺言在手动之前出现,然后在解决方案时对它们进行计数,然后
在此示例中退出相同的原则,但它具有回调功能而不是承诺。为了承诺,您将从.then()或.finally()调用计数函数,并且计数函数将决定是否该是
从JavaScript服务器退出Mongoose示例的时候:
you decide how many promises will go out before hand and then count them as they resolve, then exit
in this example the same principle is applied but it has callback functions instead of promises. For promises you would call a count function from the .then() or .finally(), and the count function will decide whether it is time to exit
mongoose example from a javascript server:
使用 Reject/Resolve 来管理 Nodejs 中的 Promise
当您的任务满足您的请求时,使用resolve()发送结果;如果失败则使用reject();
在您的情况下,您没有正确管理承诺,这就是它异步运行的原因,最好使用以下方式并获得正确的返回。
在上面的代码中,我返回查询+解析/拒绝,因此以更同步的方式运行会更好。
return conn.query(checkQuery, function (err, res) {
另外,在处理这个承诺时,我正在使用
.then((data)
处理,这样我就可以处理该解析 注意:如果您拒绝任何 Promise,则该 Promise 在上面的 .then 块中将不可用,您将在 catch 块中找到此拒绝,因此代码将按以下方式更改。
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.
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.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.
您可以尝试以下操作:
您甚至不需要调用 process.exit(0) 因为当作业完成时代码总是会终止:)
You can try the following:
You don't even need to call the process.exit(0) because the code will always terminate when the job is done :)