等待所有的承诺解决

所以我有一个情况,我有多个未知长度的承诺链。 当所有的CHAINS已经被处理时,我想要执行一些操作。 这甚至可能吗? 这里是一个例子:

app.controller('MainCtrl', function($scope, $q, $timeout) { var one = $q.defer(); var two = $q.defer(); var three = $q.defer(); var all = $q.all([one.promise, two.promise, three.promise]); all.then(allSuccess); function success(data) { console.log(data); return data + "Chained"; } function allSuccess(){ console.log("ALL PROMISES RESOLVED") } one.promise.then(success).then(success); two.promise.then(success); three.promise.then(success).then(success).then(success); $timeout(function () { one.resolve("one done"); }, Math.random() * 1000); $timeout(function () { two.resolve("two done"); }, Math.random() * 1000); $timeout(function () { three.resolve("three done"); }, Math.random() * 1000); }); 

在这个例子中,我设置了一个$q.all()来承诺一,二和三,这将在随机时间得到解决。 然后,我将承诺添加到一个和三个的结尾。 当所有的链条都解决了之后,我希望all都能解决。 这是我运行这个代码时的输出:

 one done one doneChained two done three done ALL PROMISES RESOLVED three doneChained three doneChainedChained 

有没有办法等待链条解决?

当所有的链条都解决了之后,我希望所有人都能解决。

当然,那么只要将每个链的承诺传递给all()而不是最初的承诺:

 $q.all([one.promise, two.promise, three.promise]).then(function() { console.log("ALL INITIAL PROMISES RESOLVED"); }); var onechain = one.promise.then(success).then(success), twochain = two.promise.then(success), threechain = three.promise.then(success).then(success).then(success); $q.all([onechain, twochain, threechain]).then(function() { console.log("ALL PROMISES RESOLVED"); }); 

接受的答案是正确的。 我想提供一个例子来对那些不熟悉promise人进行详细阐述。

例:

在我的例子中,我需要在渲染内容之前用不同的镜像URLreplaceimg标签的src属性。

 var img_tags = content.querySelectorAll('img'); function checkMirrorAvailability(url) { // blah blah return promise; } function changeSrc(success, y, response) { if (success === true) { img_tags[y].setAttribute('src', response.mirror_url); } else { console.log('No mirrors for: ' + img_tags[y].getAttribute('src')); } } var promise_array = []; for (var y = 0; y < img_tags.length; y++) { var img_src = img_tags[y].getAttribute('src'); promise_array.push( checkMirrorAvailability(img_src) .then( // a callback function only accept ONE argument. // Here, we use `.bind` to pass additional arguments to the // callback function (changeSrc). // successCallback changeSrc.bind(null, true, y), // errorCallback changeSrc.bind(null, false, y) ) ); } $q.all(promise_array) .then( function() { console.log('all promises have returned with either success or failure!'); render(content); } // We don't need an errorCallback function here, because above we handled // all errors. ); 

说明:

来自AngularJS 文档 :

then方法:

然后(successCallback,errorCallback,notifyCallback) – 无论何时解决或拒绝承诺,只要结果可用,就会asynchronous地调用成功或错误callback之一。 callback被调用一个参数 :结果或拒绝原因。

$ q.all(许诺)

将多个承诺组合成一个单一的承诺,当所有的input承诺都被解决时,承诺被解决。

promises参数可以是一系列的承诺。

关于bind() ,更多信息在这里: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

最近有这个问题,但与未知数量的承诺。使用jQuery.map()解决 。

 function methodThatChainsPromises(args) { //var args = [ // 'myArg1', // 'myArg2', // 'myArg3', //]; var deferred = $q.defer(); var chain = args.map(methodThatTakeArgAndReturnsPromise); $q.all(chain) .then(function () { $log.debug('All promises have been resolved.'); deferred.resolve(); }) .catch(function () { $log.debug('One or more promises failed.'); deferred.reject(); }); return deferred.promise; }