我正在使用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()
})
有什么方法可以达到这个目的吗?
答案 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。依靠承诺组合实用程序几乎总是更好的做法。