[英]$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.