【问题标题】:$q.all of AngularJS only works for one result$q.all AngularJS 只适用于一个结果
【发布时间】:2017-06-08 22:26:29
【问题描述】:

我正在研究借助 Google 距离矩阵计算从给定对象到许多其他地方的距离的函数,这当然是异步的,因此我正在处理承诺。

当位置数为 1 时,一切正常。但是,一旦我有多个承诺, $q.all 就不会做任何事情:它既不会成功解决,也不会出错。尽管我在控制台中检查了对 Google 距离矩阵的调用确实发生并返回了正确的结果。有什么线索可以在这里玩吗?

我正在使用 AngularJS 1.6.4。如果您需要更多详细信息,请告诉我。谢谢!

var requests = [];
for (var i = 0; i < ctrl.places.length; i += 1) {
    var deferred = $q.defer();
    requests.push(deferred.promise);
    var destination = ctrl.places[i].latLng;
    service.getDistanceMatrix({
        origins: [ctrl.origin],
        destinations: [destination[0] + "," + destination[1]],
        travelMode: 'DRIVING'
    }, function(response, status) {
        if (status === 'OK') {
            deferred.resolve(response.rows[0].elements[0].distance.text);
        }
    });
}

$q.all(requests).then(function(result) {
    ctrl.distances = result;
});

【问题讨论】:

    标签: angularjs angular-promise q


    【解决方案1】:

    您的问题是 var 不是块范围的,因此在调用任何回调时,deferred 的值将始终属于循环的最终迭代。这样做的结果是,更早的延迟将永远不会得到解决,$q.all 将出现挂起。

    解决此问题的最简单方法是将您对 var 的使用更改为 let 以利用块范围:

    let deferred = $q.defer();
    

    【讨论】:

    • 我喜欢你的块范围解决方案。很简单。但是,您不认为浏览器支持会是个问题吗?
    【解决方案2】:

    不起作用的原因

    当服务调用解决并调用回调处理程序时,deferred 属性指的是for 循环创建的最后一个延迟对象。因此,实际上,您始终对创建的最后一个 deferred 对象执行 resolve

    解决方案:

    创建一个新函数:

    function getDistanceMatrixForDestination (destination, origins) {
       var deferred = $q.defer();
       service.getDistanceMatrix({
            origins: [origins],
            destinations: [destination[0] + "," + destination[1]],
            travelMode: 'DRIVING'
        }, function(response, status) {
            if (status === 'OK') {
                deferred.resolve(response.rows[0].elements[0].distance.text);
            } else {
                deferred.reject();
            }
        });
       return deferred.promise;
    }
    

    将现有代码更改为:

    var requests = [];
    for (var i = 0; i < ctrl.places.length; i += 1) {
        var destination = ctrl.places[i].latLng;
        requests.push(getDistanceMatrixForDestination (destination, ctrl.origins));
    }
    
    $q.all(requests).then(function(result) {
        ctrl.distances = result;
    });
    

    【讨论】:

    • 工作就像一个魅力!太感谢了!花了好几个小时在这件事上发疯!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-26
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 2014-02-14
    • 2018-02-28
    • 2014-01-02
    相关资源
    最近更新 更多