Node.js等待异步函数完成,然后继续执行其余代码

时间:2016-06-27 16:04:51

标签: javascript node.js mongodb asynchronous mongoose

在我的代码中,我有2个for循环执行一个异步函数(它在两个循环中都是相同的函数),但是在这两个循环之后,代码必须等到它们执行之后才运行。这是我的代码:

for(var a = 0; a < videoIds.length; a++){
  if(videoIds){
    findVideo(videoIds[a], function(thumbnailPath, videoName){ // findVideo is the async function
      // it returns 2 values, thumbnailPath and videoName
      videoNames[a] = videoName; // and then these 2 values are written in the arrays
      thumbnaildPaths[a] = thumbnailPath;
      console.log('1');
    });
  }
}

// then the above code runs one more time but with different values, so I won't include it here (it's the same thing)
enter code here
console.log('3');
// the rest of the code
// writes the values from the loops to the database so I can't run it many times 

如果我运行代码,在看到1之前我会看到3(来自console.log函数)。但正如我上面所述,我必须等待循环结束才能继续前进。 findVideo()函数只包含mongoose提供的Video.find({})方法,然后返回值thumbnailPath和videoName。我需要做的是等待2个循环结束然后继续,但是由于显而易见的原因,我不能在循环中包含其余的代码!有没有什么办法解决这一问题?谢谢!

2 个答案:

答案 0 :(得分:3)

你可以使用回调,但我更喜欢承诺,因为它们很优雅。

利用Promise.all() https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

function getVideo(id){
  return new Promise(function(resolve, reject){
    findVideo(id, function(thumbnailPath, videoName){
      resolve({
        name: videoName,
      thumbnail: thumbnailPath
      });
    });
  });
}

var promises = videoIds.map(function(videoId){
  return getVideo(videoId);
});

//callback in then section will be executed will all promises will be resolved 
//and data from all promises will be passed to then callback in form ao array.
Promise.all(promises).then(function(data){
  console.log(data);
});

// Same for other list of tasks.

答案 1 :(得分:0)

最简单的解决方案是使用回调。只需将循环包装在函数中并执行类似的操作。

function findVid(callback) {
    for(var a = 0; a < videoIds.length; a++){
        if(videoIds){
            findVideo(videoIds[a], function(thumbnailPath, videoName){ // findVideo is the async function
                // it returns 2 values, thumbnailPath and videoName
                videoNames[a] = videoName; // and then these 2 values are written in the arrays
                thumbnaildPaths[a] = thumbnailPath;
                console.log('1');
                if (callback) callback(); //This will be called once it has returned
            });
        }
    }
}
findVid(function(){ 
    //this will be run after findVid is finished.
    console.log('3');
    // Rest of your code here.
});

您也可以使用Promise样式而不是回调,但两者都有工作。为了更多地了解回调和承诺,我发现了一篇很好的文章,它将更详细地解释所有内容:http://sporto.github.io/blog/2012/12/09/callbacks-listeners-promises/