Javascript 不是分阶段工作。这正常吗?

Javascript 不是分阶段工作。这正常吗?,javascript,node.js,Javascript,Node.js,例如,在处理来自数据库的数据并将其写入某个数组的复杂循环之后,我需要处理来自该数组的数据。发生的情况是,在不等待挖掘周期(填充数组)的情况下触发数组处理功能。一切都必须通过setTimeout()完成; 这正常吗 checkDialog: function (data, callback) { var interlocutorsArray = JSON.parse(data); var dialogsId = {}; mongoclient.open(function (

例如,在处理来自数据库的数据并将其写入某个数组的复杂循环之后,我需要处理来自该数组的数据。发生的情况是,在不等待挖掘周期(填充数组)的情况下触发数组处理功能。一切都必须通过setTimeout()完成; 这正常吗

checkDialog: function (data, callback) {
    var interlocutorsArray = JSON.parse(data);
    var dialogsId = {};
    mongoclient.open(function (err, cursor) {

        var db = cursor.db('messages');
        var dialogsDb = db.collection('dialog');
        interlocutorsArray.forEach(function (item, index) {
            dialogsDb.find({
                owner: item.owner_user_id,
                viewer: item.viewer_user_id
            }, function (err, cursor) {
                cursor.count(function (err, count) {
                    if (count === 0) {
                        dialogsDb.insert({
                            owner: item.owner_user_id,
                            viewer: item.viewer_user_id
                        }, function (err, inserting) {
                            dialogsId[inserting[0]._id] = {
                                owner: item.owner_user_id,
                                viewer: item.viewer_user_id
                            };
                        });
                    } else {
                        cursor.each(function (err, item) {
                            if (item !== null) {
                                dialogsId[item._id] = {
                                    owner: item.owner,
                                    viewer: item.viewer
                                };
                            }
                        });
                    }
                });
            });
        });
    });

    setTimeout((function () {
        callback(dialogsId);
    }), 150);

    console.log('after callback');

}

对不起,我的英语不好

首先,我建议您从当前的
mongodb
模块切换到更舒适的模块,例如:

在我的示例中,我将使用
monk
,因为它可以很容易地适应任何
mongodb
模块,包括

对于您的问题,您可以使用任何异步控制流管理模块来解决,例如:

  • 大多数,例如
下面是一个使用
async.js
解决问题的示例:

checkDialog: function (data, callback) {
  var db = require('monk')('localhost/messages');
  var dialogsDb = db.get('dialog');
  var interlocutorsArray = JSON.parse(data);

  async.concat(interlocutorsArray, function (item, next) {
    var query = {
      owner: item.owner_user_id
      viewer: item.viewer_user_id
    };
    dialogsDb.find(query, function (err, docs) {
      if (err) return next(err);
      if (docs && docs.length > 0) {
        next(null, docs);
      } else {
        dialogsDb.insert(query, function (err, inserting) {
          next(err, [inserting]);
        })
      }
    })
  }, function (err, items) {
    if (err) throw err; // it's best to handle errors without throwing them
    var dialogsId = {};
    for (var item, i = 0; i < items.length; i++) {
      item = items[i];
      dialogsId[item._id] = {
        owner: item.owner,
        viewer: item.viewer
      };
    }
    callback(dialogsId);
  })
}
checkDialog:函数(数据,回调){
var db=require('monk')('localhost/messages');
var dialogsDb=db.get('dialog');
var interlocatorsarray=JSON.parse(数据);
concat(对话者数组,函数(项,下一个){
变量查询={
所有者:item.owner\u用户\u id
查看器:item.viewer\u用户\u id
};
dialogsDb.find(查询、函数(错误、文档){
if(err)返回next(err);
如果(docs&&docs.length>0){
下一步(空,文档);
}否则{
对话框SDB.insert(查询,函数(错误,插入){
下一步(呃,[插入]);
})
}
})
},功能(错误,项目){
if(err)throw err;//处理错误时最好不要抛出错误
var dialogsId={};
对于(变量项,i=0;i
你在地狱里。@alex那太糟糕了:(但是,我该怎么办?我不明白问题是什么?…对不起…@gillyb看…我需要从数据库中填充一个数组dialogsId数据。结果很好。接下来,我需要解析这个数组,这将在主循环对话器array.forEach之后完成。问题是循环后的dialogsId只有在一段时间后才可用。That是,现在我只能通过setTimeout()获得它;如何避免它?Javascript是非阻塞的,因此不需要等待处理完成。处理完成后,您需要调用回调函数。不。设置超时不是正常的做法。它也非常不可靠。回调是Javascript中处理事情的正常方式。如果您不满意,请有了这个,您可以随时切换到阻塞。您的答案非常完美!您对解决我的问题非常有帮助!但是,我并不完全理解您的代码。我想对所有代码进行分段解析。谢谢您的帮助!