首页 > 解决方案 > 如何仅在另一个使用 express js 完成时运行查询

问题描述

请对我温柔一点,我是 node js 的新手。我在 for 循环中运行两个查询,将值插入到两个名为 orders 和 requests 的表中。在插入订单表后,我将 insertId 传递给变量 orderid,然后将其添加到我的第二个插入查询中。所有这些工作正常,完成后我想查询一个名为 invoice 的视图,以便我可以获得一些我刚刚放入数据库的信息。问题是它甚至在完成两个查询之前就从视图返回结果,因此我得到一个空响应。这是我的代码。

for(var i = 0; i<items.length; i++){
  connection.query('INSERT INTO orders(referenceid,itemid,quantity,dac,requestid,locationid) VALUES(?,?,?,?,?,?);',[referenceid,items[i].id,items[i].quantity,dac,requestid,locationid], function(errors,results,fields){
                if(errors){ throw errors};
                    var orderid = results.insertId;
                connection.query('INSERT INTO requests(requestid,orderid,price) VALUES(?,?,?)',[requestid,orderid,price],function(errors,results,fields){
                })
  })

}
connection.query('SELECT * FROM invoice WHERE requestid = ? ,[requestid],function(errors,results,fields){
                })

所以任何人都可以帮助我让 SELECT 查询仅在 for 循环中的所有插入完成时运行。我的数据库是mysql。

标签: mysqlnode.jsexpressasynchronousasync-await

解决方案


我不确定您使用的是哪个 SQL npm 模块,因此我无法参考任何文档,但我相信发生的事情是您被调用的connection.query()是异步的,因为它们应该是异步的。这会导致您connection.query()在 for 循环之外的最终结果在 for 循环内部的那些之前执行,因此,您将无法requestId在最终查询中使用。

我可以立即提供两种可能的解决方案,包括:

  • 将您的查询调用嵌套到回调中
  • 使用明确的承诺

因此,对于第一个选项,您只需将最终查询放入查询的嵌套回调中即可requestsinvoice据我了解,您只希望在插入orders&requests完成后从中选择行。

至于第二个选项,您可以将 for 循环的内容重构为辅助函数并将其封装为return new Promise()如下所示:

const helper = (<any_params_you_need>) => {
   return new Promise(resolve, reject) => {
      for(var i = 0; i<items.length; i++){
         connection.query('INSERT INTO orders(referenceid,itemid,quantity,dac,requestid,locationid) VALUES(?,?,?,?,?,?);',[referenceid,items[i].id,items[i].quantity,dac,requestid,locationid], function(errors,results,fields){
                if(errors) { reject(err); }
                var orderid = results.insertId;
                connection.query('INSERT INTO requests(requestid,orderid,price) 
                VALUES(?,?,?)', 
                [requestid,orderid,price],function(errors,results,fields){
                    resolve(results);
                })
         })
      }
   }
}

一旦你设置了帮助函数,你就可以await像这样调用它:await helper();在你的选择查询之前。例如,在调用函数中,它看起来像:

...
const results = await helper();
connection.query('SELECT * FROM invoice WHERE requestid = ? ,[requestid],function(errors,results,fields){});
...

推荐阅读