我想要一个for循环,该循环在每次迭代时调用异步函数。
在for循环之后,我想执行另一个代码块,但在解决for循环中的所有先前调用之前,不要执行。
目前我的问题是,在所有异步调用完成之前执行了for循环之后的代码块,或者根本不执行该代码块。
带有FOR循环的代码部分及其后的代码块(有关完整代码,请参阅fiddle):
[..] function outerFunction($q, $scope) { var defer = $q.defer(); readSome($q,$scope).then(function() { var promise = writeSome($q, $scope.testArray[0]) for (var i=1; i < $scope.testArray.length; i++) { promise = promise.then( angular.bind(null, writeSome, $q, $scope.testArray[i]) ); } // this must not be called before all calls in for-loop have finished promise = promise.then(function() { return writeSome($q, "finish").then(function() { console.log("resolve"); // resolving here after everything has been done, yey! defer.resolve(); }); }); }); return defer.promise; }
我创建了一个jsFiddle,可以在http://jsfiddle.net/riemersebastian/B43u6/3/中找到。
目前看来执行顺序很好(请参阅控制台输出)。
我的猜测是,这仅仅是因为每个函数调用都会立即返回,而无需执行任何实际工作。我试图用setTimeout延迟defer.resolve,但是失败了(即最后一个代码块从未执行过)。您可以在小提琴的注释框内看到它。
当我使用写入文件和从文件读取的实函数时,在最后一次写操作完成之前执行了最后一个代码块,这不是我想要的。
当然,该错误可能出在那些读/写功能之一中,但我想验证一下我在此处发布的代码没有问题。
您需要使用的是$ q.all,它将多个诺言合并为一个诺言,只有当所有诺言都得到解决后才能解决。
在您的情况下,您可以执行以下操作:
function outerFunction() { var defer = $q.defer(); var promises = []; function lastTask(){ writeSome('finish').then( function(){ defer.resolve(); }); } angular.forEach( $scope.testArray, function(value){ promises.push(writeSome(value)); }); $q.all(promises).then(lastTask); return defer.promise; }