Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 在javascript中如何将setTimeout与双回调一起使用_Node.js_Loops_Callback_Mongoose - Fatal编程技术网

Node.js 在javascript中如何将setTimeout与双回调一起使用

Node.js 在javascript中如何将setTimeout与双回调一起使用,node.js,loops,callback,mongoose,Node.js,Loops,Callback,Mongoose,编辑:我在中用更简单的代码和更多的信息重写了这个问题。我将此保留为原样,以便人们可以根据自己的意愿参考详细的代码 我有一个Mongoose,带有子文档的节点设置。我需要调用一个函数,使用setTimeout根据某些条件更新一个数字。然而,有时由于回调没有快速返回,它会进入竞争状态。这里是一个示例方法 function myProcessPump(){ //Get top level documents based on some condition UserInfo

编辑:我在中用更简单的代码和更多的信息重写了这个问题。我将此保留为原样,以便人们可以根据自己的意愿参考详细的代码

我有一个Mongoose,带有子文档的节点设置。我需要调用一个函数,使用setTimeout根据某些条件更新一个数字。然而,有时由于回调没有快速返回,它会进入竞争状态。这里是一个示例方法

function myProcessPump(){
    //Get top level documents based on some condition
    UserInfo
        .where('some_condition').lte(new Date())
        .exec(function(err, UserInfoRetArray){
         if (!err) {
             if (UserInfoRetArray.length > 0){
                 //Iterate thru the top level documents
                 for (var i = 0; i < UserInfoRetArray.length; i++){
                     //Iterate thru sub-documents
                     for (var j = 0; j < UserInfoRetArray[i].someItems.length; j++){
                        // do some work...
                        do_work(UserInfoRetArray[i].someItems[j]);
                        //update status in db
                         set['someItems.$.some_condition'] = new Date((new Date()).getTime() + 10000) ;
                         UserInfo.update({_id: UserInfoRetArray[i]._id, "someItems._id":UserInfoRetArray[i].someItems[j]._id}, 
                            {$set: set}, function(err, numAffected) {
                            //set timeout so myProcessPump is called again.
                            setTimeout(myProcessPump, 1000);
                            });
                         }
                   }
              } else {
                //set timeout so myProcessPump is called again.
                setTimeout(myProcessPump, 1000);
                // I suspect this gets called when the previous call back does not 
                // complete in time causing the mulitple timers running in parallel.
              }
           } else {
             //set timeout so myProcessPump is called again.
             setTimeout(myProcessPump, 1000);
         }
    })
}
函数myProcessPump(){
//根据某些条件获取顶级文档
用户信息
.where('some_condition').lte(新日期())
.exec(函数(err,userinfortaray){
如果(!err){
如果(userinfortaray.length>0){
//遍历顶级文档
for(var i=0;i

我简化了代码来解释我想要什么。如何在不发生竞争条件的情况下成功调用setTimeout?

未测试,但您可以尝试以下方法:

function myProcessPump() {
  //Get top level documents based on some condition
  UserInfo
    .where('some_condition').lte(new Date())
    .exec(function(err, UserInfoRetArray) {
      //Wrap everything in an async function with a callback
      var processUser = function(done) {
        if (!err) {
          if (UserInfoRetArray.length > 0) {
            //Iterate thru the top level documents
            for (var i = 0; i < UserInfoRetArray.length; i++) {
              //Iterate thru sub-documents
              for (var j = 0; j < UserInfoRetArray[i].someItems.length; j++) {
                // do some work...
                do_work(UserInfoRetArray[i].someItems[j]);
                //update status in db
                set['someItems.$.some_condition'] = new Date((new Date()).getTime() + 10000);
                UserInfo.update({
                  _id: UserInfoRetArray[i]._id,
                  "someItems._id": UserInfoRetArray[i].someItems[j]._id
                }, {
                  $set: set
                }, function(err, numAffected) {

                  done();
                });
              }
            }
          } else {
            done();
          }
        } else {
          done();
        }
      }
      //Call async function and when done redo the whole thing
      processUser(function() {
        //probably done need the timeout and can just call myProcessPump unless you really need a delay
        myProcessPump();
        //setTimeout(myProcessPump, 1000);
      })
    })
}
函数myProcessPump(){
//根据某些条件获取顶级文档
用户信息
.where('some_condition').lte(新日期())
.exec(函数(err,userinfortaray){
//用回调函数将所有内容包装在异步函数中
var processUser=函数(完成){
如果(!err){
如果(userinfortaray.length>0){
//遍历顶级文档
for(var i=0;i
您的问题仍然过于本地化。你需要试着找出问题的根源并询问它。明白了…我会相应地编辑。如果您可以用香草JS(更少的需求)编写这篇文章,这会有所帮助。当然,这并不总是可能的,我想在上面的代码中保留双循环和回调的风格。如果我改变它,那么它会显著地改变意图。但我还是会尝试的。我在中重写了这个问题