【问题标题】:How to execute nested queries within async and conditional loop in node.js如何在 node.js 的异步和条件循环中执行嵌套查询
【发布时间】:2018-11-25 05:30:48
【问题描述】:

我在我的项目中使用 node.js、express 和 postgres db。我在异步函数中有几个查询,我无法按顺序执行。示例代码供参考。

for(let i=0;i<person_size;i++)
{
    var check_person_query="select per_id_pk from person_tbl where per_fname='"+person_fname[i]+"' and per_lname='"+person_lname[i]+"'";

    dbClient.query(check_person_query,function(err,result){
        if(result.rows.length>0)
        {
            console.log("Call: 1.1");
            console.log("person already exists");
        }
        else
        {
            var insert_person_query = "insert into person_tbl (per_fname,per_lname,per_gender,profile_photo) values('"+person_fname[i]+"','"+person_lname[i]+"','"+person_gender[i]+"','profile_photo_link')";
            //console.log("query2: "+insert_person_query);
            dbClient.query(insert_person_query,function(err,result){
                    if (err) throw err;
                    console.log("Call: 1.2");
                    console.log("New person has been added");       
            });

            var fullname = person_fname[i].concat(person_lname[i]);
            low_fullname = fullname.toLowerCase();

            person_pic[i].mv("/home/aniket/content_info/images/"+low_fullname+".jpg", function(err){
                if (err) throw err;
            });                                             
        }
    });
}//end for 

在上面的代码中,当 if 条件失败时,else 部分会在我的 async.series 函数的最后执行。只要条件成功,一切都会按顺序完美运行。如何顺序运行嵌套的数据库查询?我使用了 async.waterfall 但仍然没有预期的输出。

更新:(已解决)

我没有使用嵌套查询函数,而是删除了嵌套,并准备了单个查询,以便获得预期的结果并保持执行顺序。

【问题讨论】:

  • 你总是可以使用 promises 和 async/await,后者自然适用于循环。

标签: node.js postgresql express async.js


【解决方案1】:

你真的应该只使用 async/await。 pg lib supports promises,所以你可以这样做:

for(let i=0;i<person_size;i++) {
  const result = await dbClient.query(check_person_query);
  if(result.rows.length <= 0) {
    await dbClient.query(insert_person_query);
  }
}

这里有更多关于using for loops with async/await的信息。

【讨论】:

  • 感谢@vkarpov15 的详细回答。我正在用头撞墙以寻求解决方案。作为一种解决方法,我不得不消除对嵌套查询函数的需求。仍然有一个问题,为什么嵌套查询根本不起作用。我会试试你的解决方案。
  • 就性能而言,此解决方案将是最慢的,因为它将是完全同步的。一个合适的解决方案应该是异步的,并且在可能的情况下使用联合查询。而且,这取决于person_size 中的值范围。
  • 这个解决方案不会完全同步,这就是为什么它被称为 async/await :)
  • @vkarpov15 这就是它的名字?哈哈。所以你不知道async/await 在 JavaScript 中充当了阻塞操作。此代码将同步执行。
  • @vitaly-t 那么我们如何才能以更快的方式开发解决方案呢?
【解决方案2】:

试试这个,我刚刚在查询函数的回调中移动了图像处理代码,所以它应该按顺序运行。

for(let i=0;i<person_size;i++)
    {
        var check_person_query="select per_id_pk from person_tbl where per_fname='"+person_fname[i]+"' and per_lname='"+person_lname[i]+"'";

        dbClient.query(check_person_query,function(err,result){
        if(result.rows.length>0)
        {
            console.log("Call: 1.1");
            console.log("person already exists");
        }
        else
        {
            var insert_person_query = "insert into person_tbl (per_fname,per_lname,per_gender,profile_photo) values('"+person_fname[i]+"','"+person_lname[i]+"','"+person_gender[i]+"','profile_photo_link')";
            //console.log("query2: "+insert_person_query);
            dbClient.query(insert_person_query,function(err,result){
            if (err) throw err;
            console.log("Call: 1.2");
            console.log("New person has been added");

            var fullname = person_fname[i].concat(person_lname[i]);
            low_fullname = fullname.toLowerCase();

            person_pic[i].mv("/home/aniket/content_info/images/"+low_fullname+".jpg", function(err){
                if (err) throw err;
            });
        });

        }
    });
    }//end for 

【讨论】:

  • 即使我也认为它可能是主要障碍,但是作为异步结构的新手我错了。
猜你喜欢
  • 2015-06-05
  • 1970-01-01
  • 2017-04-08
  • 2016-06-17
  • 1970-01-01
  • 2015-11-30
  • 2019-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多