簡體   English   中英

$ q.all()Angular.js中的多個調用

[英]$q.all() multiple calls in Angularjs

我有一個在click事件上調用的函數。 它有一個驅動程序列表,我希望通過Google定向服務針對每個驅動程序提供ETA。 這是我的代碼:

var deferred = $q.defer();
var urlCalls = [];

function getDriversEta(jobLoc, drivers) { //this function gets invoke on click.
    angular.forEach(drivers, function (value, key) {
        value.eta = undefined;
        urlCalls.push(GetDriverMatrix(jobLoc.lat, jobLoc.lon,
            value.Location.Latitude, value.Location.Longitude, function (response) {
                value.eta = formatSecondsToTime(response.routes[0].legs[0].duration.value);
                deferred.resolve(value);
            }));
    });
    $q.all(urlCalls).then(
        function (results) {
            var check = results;
        },
        function (errors) {
            //deferred.reject(errors);
        },
        function (updates) {
            //deferred.update(updates);
        });
}

function GetDriverMatrix(pickupLat, pickupLon, driverLat, driverLon, callBack) {
    var directionsService = new google.maps.DirectionsService();
    var directionsRequest = {
        origin: new google.maps.LatLng(driverLat, driverLon),
        destination: new google.maps.LatLng(pickupLat, pickupLon),
        travelMode: google.maps.DirectionsTravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.METRIC
    };
    directionsService.route(directionsRequest, function (response, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            callBack(response);
        }
    });

    return deferred.promise;
}

第一次工作正常,但給出了重復的值。 但是在第二個click事件上,然后$ q.all()函數在回調響應之前觸發。 我在這里做錯了什么? 我是新來的諾言。

您有幾個問題:

1)您正在執行多個異步操作,但是只有一個延遲對象,所有這些對象都在使用該對象。 因此,只要他們中的任何一個解決了該問題,他們都將被有效解決。 相反,他們每個人都需要自己的。
2)GetDriverMatrix似乎同時在執行回調方法和Promise方法。 只選一個(我建議諾言)。

因此,讓我們從修復GetDriveMatrix開始:

//** Callback parameter removed
function getDriverMatrix(pickupLat, pickupLon, driverLat, driveLon) {
    var deferred = $q.defer(); //** create a new deferred each time
    var directionsService = new google.maps.DirectionsService();
    var directionsRequest = {
        origin: new google.maps.LatLng(driverLat, driverLon),
        destination: new google.maps.LatLng(pickupLat, pickupLon),
        travelMode: google.maps.DirectionsTravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.METRIC
    };
    directionsService.route(directionsRequest, function (response, status) {
        if (status == google.maps.DirectionsStatus.OK) {
        deferred.resolve(response); //** resolve instead of calling callback
    } else {
        deferred.reject(response); //** reject if there's an error
    }
    return deferred.promise;
});

現在,要使用它,您基本上處於正確的軌道上,但是我需要更改的內容很少:

1)由於我刪除了getDriverMatrix的回調部分,因此我們將使用Promise。
2)將允諾數組放在函數內部,而不是函數外部。 沒有其他人需要查看該數組,因此無需公開它
3)而不是做一個foreach,然后推入一個數組,我會使用array.map。 它專為此類情況而設計,免除了您手動執行推送的麻煩。

function getDriversEta(jobLoc, drivers) {
    //** Using array.map to produce a new array of promises
    var promises = drivers.map(function (driver) {
        return GetDriverMatrix(jobLoc.lat, jobLoc.lon, driver.Location.latitude, driver.Location.longitude)
            //** using the .then method instead of callback
            .then(function (response) {
                driver.eta = formatSecondsToTime(response.routes[0].legs[0].duration.value);
                return driver;
            });
    });

    $q.all(promises).then(
        function (results) {
            var check = results;
        },
        function (errors) {

        },
        function (updates) {

        });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM