【问题标题】:NodeJS Synchronous Trouble [duplicate]NodeJS同步故障[重复]
【发布时间】:2017-09-20 04:39:33
【问题描述】:

使用 NodeJS,我试图从数据库中获取关于 ID 列表的信息并填充对象数组。我需要这个来同步处理。我无法弄清楚如何执行此操作,因此下一个函数调用将等待前一个函数调用完成,然后再被调用。然后完成所有“每个”迭代以调用返回。

例子:

getInfo();

function getInfo(){
   var return_arr = Array();
   var ids = getListOfIDs();
   // loop through each id getting more info from db
   $.each( ids, function( i, v ){
       return_arr.push(getFullInfo( id ));
   });
   return return_arr;
}

function getListOfIDs(){
  // database call to get IDs
  // returns array
}

function getFullInfo(){
  // database call to get full info
  // returns object
}

这是一个简化的示例,因此假设获取所有信息的单个查询将不起作用,因为需要在 js 中进行多个连接和后处理。另外,假设我正在做正确的错误处理,我在我的例子中省略了。

【问题讨论】:

    标签: javascript node.js asynchronous synchronous


    【解决方案1】:

    您的数据库查询是异步的,因此您需要使用回调或承诺在数据库返回结果后执行您的工作。

    function getListOfIDs(callback) {
      // database call to get IDs
      db.query('...', function(data) {
        // call the callback and pass it the array
        callback(data);
      });
    }
    
    function getInfo() {
      // pass an anonymous function as a callback
      getListofIDs(function(data) {
        // we now have access to the data passed into the callback
        console.log(data);
      });
    }
    

    【讨论】:

    • 回调不能确保同步处理调用。你能提供一个带有承诺的代码示例吗?
    • Callbacks 确保调用以我的理解同步处理。你只需要用后面的调用前面的。
    • 当然,如果没有嵌入多个级别,promise 代码会更干净。但是回调应该没有解决同步问题的问题。
    • @user6041966 回调和承诺的工作方式相同;两者都是异步的。在调用处理函数之前,两者都等待长时间运行的操作完成。当该操作完成时,两者都保证会触发。既不是同步的,也不是你的数据库查询代码。
    【解决方案2】:

    您当前的代码示例是同步的,尽管我不知道您的数据库代码是如何工作的。每个循环都是同步的,它只是遍历您的 id 并调用 getFullInfo 函数。

    我不确定您为什么需要同步代码,因为它不使用 Nodes 事件循环架构。

    我要做的是使用一个好的 Promises 框架,例如 Bluebird (http://bluebirdjs.com/docs/api/promise.each.html) 和 Promise.each,确保每次迭代都是连续发生的。或者你也可以使用回调库,例如 async (http://caolan.github.io/async/) 和 async.eachSeries。其中任何一个都将确保您 (a) 获得异步的好处并 (b) 以串行方式进行迭代。

    【讨论】:

      【解决方案3】:

      承诺的方法:

      function getListOfIDs() {
        return new Promise((resolve, reject) => {
             // database call
             if (err) 
             {
                 reject(your_db_err);
                 return;
             }
             resolve(your_db_result);
        });
      }
      
      function getInfo() {
          getListOfIDs().then((result) => {
              //do whatever you want with result
          })
          .catch((err) => {
              //handle your err
          });
      }
      

      【讨论】:

      • 我为什么要投反对票?
      • 老实说,我认为这不值得投反对票(并且个人讨厌没有 cmets 的投反对票),但也​​许是解决/拒绝处理缺乏条件?
      • 也许这就是问题所在。我会添加它。
      • 代码格式不一致、缺乏解释错误以及为什么需要此更改等
      • @KevinB 感谢您的评论。作者只问了异步处理的例子。我浏览了 Soviut 的帖子并发布了这个答案。这就是为什么它缺乏解释。我应该提一下。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-22
      • 2014-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多