等待所有承诺解决

jen*_*gar 106 promise angularjs angular-promise

所以我有一种情况,我有多个未知长度的承诺链.我希望在处理完所有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);
});
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我设置了一个$q.all()承诺一,二和三,这将在一些随机时间得到解决.然后我将承诺添加到第一和第三的末尾.我想要all解决所有链都已解决的问题.这是我运行此代码时的输出:

one done 
one doneChained
two done
three done
ALL PROMISES RESOLVED
three doneChained
three doneChainedChained 
Run Code Online (Sandbox Code Playgroud)

有没有办法等待连锁店解决?

Ber*_*rgi 158

当所有链都已解决时,我希望所有人都解决.

当然,然后将每个链的承诺传递给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");
});
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你确认我最害怕的事情.现在我必须想出一个方法来获得最后的承诺大声笑. (2认同)

Hie*_*ieu 16

接受的答案是正确的.我想举一个例子来向那些不熟悉的人详细说明promise.

例:

在我的示例中,我需要在呈现内容之前用不同的镜像URL 替换标记的src属性(img如果可用).

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.
);
Run Code Online (Sandbox Code Playgroud)

说明:

来自AngularJS 文档:

then方法:

然后(successCallback,errorCallback,notifyCallback) - 无论何时或将要解决或拒绝承诺,只要结果可用,就会异步调用其中一个成功或错误回调.使用单个参数调用回调:结果或拒绝原因.

$ q.all(许诺)

将多个promise组合成一个promise,在解析所有输入promise时解析.

promises参数可以是一系列承诺.

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