如何确定何时完成javascript循环?

时间:2016-06-05 13:49:37

标签: javascript lodash

我正在使用Lodash ForeEach,我想确定何时完成循环并运行返回解析承诺。

   return $q(function (resolve, reject) {
    _.forEach(arrayOfFiles, function (file) {
      var url = file.link;
      //Download file in device ()
    });

    //her i wont to resolve after finish looping
    resolve()
  })

有什么方法可以达到这个目的吗?

3 个答案:

答案 0 :(得分:1)

您不需要"确定"任何事情,跟随_.forEach()后面的任何代码都会在循环结束后执行

_.forEach(arrayOfFiles, function (file) {
      var url = file.link;
      //Download file in device ()
    });

callAnotherMethod();

PS。您的" 设计中的下载文件"评论表明你可能会担心异步调用。好吧,那些必须在那些异步调用中处理。

答案 1 :(得分:0)

您需要一个变量来计算完成的迭代次数,以便您可以检查计数器是否等于处理迭代的元素数量。

 counter = 0;
 _.forEach(arrayOfFiles, function (file) {
  var url = file.link;
  //Download file in device ()
  counter++;
  if(counter == _.length){
        //it's finished
  }
});

答案 2 :(得分:0)

forEach是一个同步操作。因此,当调用resolve()时,可以保证所有迭代都已运行。

但是,您似乎打算在每次迭代中执行一些异步操作,并希望等待所有这些操作完成。这可以通过承诺优雅地处理。

我们假设你有一个downloadFile异步函数返回一个promise(如果没有,使用promisify),你可以将arrayOfFiles映射到promises数组并使用Promise.all来组合数组如果数组中的所有promise都已解决,则对单个promise的承诺将被解析。

return $q(function (resolve, reject) {
   var arrayOfPromises = _.map(arrayOfFiles, function (file) {
     var url = file.link;
     return downloadFile(url)
   });

   Promise
     .all(arrayOfPromises)
     .then(resolve)
     .catch(reject);
});

此时应该很明显,您根本不需要调用promise构造函数。你可以写:

return Promise.all(_.map(arrayOfFiles, function (file) {
  return downloadFile(file.link)
}))

利用ES6功能可以更加简洁:

return Promise.all(arrayOfFiles.map(({ link }) => downloadFile(link)))

事实上,明确地创建了一个反模式的承诺should be considered。依靠承诺组合实用程序几乎总是更好的做法。