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

查看:80
本文介绍了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

推荐答案

角度文档没有详细介绍,但我相信$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都会立即以拒绝的承诺的值来拒绝,并丢弃所有其他承诺,无论它们是否已解决.

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/zh-CN/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天全站免登陆