Angular $q.all 在第一个承诺完成后被调用 [英] Angular $q.all gets called after first promise finished

查看:22
本文介绍了Angular $q.all 在第一个承诺完成后被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 $q.all 等待所有承诺都得到解决,但它在第一个承诺完成后被调用!

I'm trying to use $q.all to wait until all promises are resolved but it's called after first promise is finished!

我做错了什么?

function sendAudits(audits) {
    var promises = [];

    $scope.sendAudits = {
        progress: 0
    };
    angular.forEach(audits, function (audit, idAudit) {
        promises.push(saveAudit(audit));
    });

    $q
        .all(promises)
        .then(function (data) {
            console.log(data);
        }, function (errors) {
            console.log(errors);
        });
}

function saveAudit(audit) {
    var filename = audit.header.id + ".txt";

    return $http({
        method: 'PUT',
        url: '/audits/audits.php?filename=' + encodeURIComponent(filename),
        data: AuditSvc.getPlainAudit(audit.header.id)
    }).finally(function () {
        $scope.sendAudits.progress += 1;
        console.log("FINALLY: " + audit.header.id);
    });
}

编辑

再深入一点分析这个问题,当一些响应是错误的时候就会出现这种情况.例如,当服务器返回 header("HTTP/1.0 418 I'm A Teapot: " . $filename); 时,客户端控制台将类似于:

Analysing a little bit deeper the problem, this situation occurs when some of the responses are error. For example when the server returns header("HTTP/1.0 418 I'm A Teapot: " . $filename);, client console would be like:

PUT http://localhost:8182/audits/audits.php?filename=1.txt 418 (I'm A Teapot: 1.txt)
FINALLY: 1
Object {data: "", status: 418, config: Object, statusText: "I'm A Teapot: 1.txt"}
PUT http://localhost:8182/audits/audits.php?filename=2.txt 418 (I'm A Teapot: 2.txt)
FINALLY: 2
PUT http://localhost:8182/audits/audits.php?filename=3.txt 418 (I'm A Teapot: 3.txt)
FINALLY: 3
PUT http://localhost:8182/audits/audits.php?filename=4.txt 418 (I'm A Teapot: 4.txt)
FINALLY: 4

推荐答案

angular 文档没有详细介绍,但我相信 $q.all() 在这种情况下的行为方式相同如 es2015 Promise.all():

The angular documentation doesn't go into detail, but I believe $q.all() behaves in this case the same way as the es2015 Promise.all():

如果任何传入的 promise 被拒绝,则 all Promise 会立即拒绝,并使用被拒绝的 Promise 的值,丢弃所有其他 Promise,无论它们是否已解决.

If any of the passed in promises rejects, the all Promise immediately rejects with the value of the promise that rejected, discarding all the other promises whether or not they have resolved.

最有可能的情况是,您的至少一个请求失败了.您的日志语句不区分 $q.all() 是成功还是失败,但如果失败,您将看到的只是第一个错误.

Most likely what is happening here is that at least one of your requests is failing. Your log statements don't distinguish whether the $q.all() succeeded or failed but if it is failing all you will see is the first error.

参见 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all 引用来源.

如果您想获得所有响应,即使有些响应失败,那么您应该在 saveAudit 中添加一个 catch 处理程序以将失败转换为成功响应:

If you want to get all of the responses, even when some fail, then you should add a catch handler in saveAudit to convert the failures into successful responses:

function saveAudit(audit) {
    var filename = audit.header.id + ".txt";

    return $http({
        method: 'PUT',
        url: '/audits/audits.php?filename=' + encodeURIComponent(filename),
        data: AuditSvc.getPlainAudit(audit.header.id)
    }).catch(function(error) {
        return { error:error};
    })
    .finally(function () {
        $scope.sendAudits.progress += 1;
        console.log("FINALLY: " + audit.header.id);
    });
}

然后您需要检查每个响应以查看它是否包含错误或有效数据.

and then you need to check each response to see whether it contains an error or valid data.

这篇关于Angular $q.all 在第一个承诺完成后被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆