Angularjs 等待所有承诺得到解决

Angularjs 等待所有承诺得到解决,angularjs,promise,angular-promise,Angularjs,Promise,Angular Promise,所以我有一个情况,我有多个未知长度的承诺链。我希望在处理完所有链后运行一些操作。这可能吗?以下是一个例子: 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.p

所以我有一个情况,我有多个未知长度的承诺链。我希望在处理完所有链后运行一些操作。这可能吗?以下是一个例子:

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()
,这些承诺将在某个随机时间得到解决。然后,我在第一和第三段的末尾加上承诺。我希望在解析所有链后解析
所有
。以下是我运行此代码时的输出:

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

有没有办法等待链解析?

有办法<代码>$q.all(…

您可以检查以下资料:

我希望在所有链都已解决时解决所有问题

当然,然后只需将每条链的承诺传递到
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
的人举个例子来详细说明一下

示例:

在我的示例中,我需要在呈现内容之前使用不同的镜像URL(如果可用)替换
img
标记的
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.
);
var img_tags=content.querySelectorAll('img');
功能检查镜像可用性(url){
//废话
回报承诺;
}
函数更改(成功、y、响应){
如果(成功===true){
img_标记[y].setAttribute('src',response.mirror_url);
} 
否则{
console.log('No-mirrors for:'+img_标记[y].getAttribute('src'));
}
}
var_数组=[];
对于(变量y=0;y
说明:

来自AngularJS:

然后
方法:

然后(successCallback、errorCallback、notifyCallback)–无论承诺何时或将何时解决或拒绝,然后调用 一个成功或错误回调会在 结果可用。调用回调时使用单个 参数:结果或拒绝原因

$q.all(承诺)

将多个承诺合并为单个承诺,并在 所有输入承诺都已解决

承诺
参数可以是承诺数组


关于
bind()
,此处有更多信息:

最近出现此问题,但承诺数量未知。使用解决

你可以用

注意:我不能100%确定您可以从非异步函数调用异步函数并获得正确的结果

也就是说,这将永远不会在网站上使用。但对于负载测试/集成测试…也许

示例代码:

异步函数waitForIt(printMe){
console.log(printMe);
log(“…”+等待请求());
log(“传奇!”)
}
函数req(){
var承诺=新承诺(解决=>{
设置超时(()=>{
决心(“DARY!”);
}, 2000);
});
回报承诺;
}

waitForIt(“Legen Wait”);
这要求我知道我的链条长度,对吗?我的意思是,如果我承诺长度为10,我就必须做
$q.all([p1.然后(…)。然后(…)。然后(…)。然后(…)。然后(…)。)
对吗?谢谢你确认我最担心的事情。现在我必须想出一个方法来获得最后的承诺。这有什么问题吗?你的链是动态构造的吗?这正是我的问题。我正在尝试动态创建一个承诺链,然后我想在链完成后做些什么。你能给我们看看你的代码吗(可能会问一个新问题)?在执行
Q.all
之后,是否有附加到链中的项目?否则它应该很简单?我很想向您展示代码…但我还没有写完,但是我会尽力解释。我有一个“操作”列表这需要完成。这些操作可能有任意级别的子操作与之关联。我希望在所有操作及其子操作完成后能够执行某些操作。可能会有多个
$q。所有
s,但是一旦我开始解决过程,就不会链接新的操作/承诺。
然后
$q.all
方法提供了一个返回承诺的数组,因此您可以循环该数组并对数组中的每个项调用
then
,而不是在将承诺添加到
promise\u数组
时调用
then
。这不是jQuery.map(),而是array.prototype.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;
}
app.controller('MainCtrl', async function($scope, $q, $timeout) {
  ...
  var all = await $q.all([one.promise, two.promise, three.promise]); 
  ...
}