“AddDistance”是DB函数的插入, 问题是hash [k] [2]值随循环跳转而“distance”(服务承诺)仍在等待,结果我向我的DB插入了错误的行。
如何在“AddDistance()”运行之前保持循环跳转到下一个对象,我应该使用Q $,while,.then()吗?
我尝试了上述但失败了,可能没有正确地做到。
请告知......
sql("""SELECT CAST(dayToInt(date_format(dateEst, 'EEEE')) AS float) AS dayOfWeekInt
FROM data""")
答案 0 :(得分:1)
通过将promises链接在一起而不是并行运行,可以确保长时间运行的操作一次运行一个。需要注意确保参数正确传递,因为循环将在任何长时间运行的函数被调用之前完成。
因为函数按顺序执行,所以可以将结果存储在数组中并确保它们按顺序排列。
var promise = $q.resolve();
var distances = [];
for (var k in hash) {
promise = chainPromise(promise, callGoogleMaps, k);
};
promise.then(function () {
console.log('forEach loop completed. Do Something after it...',
distances);
});
function chainPromise(promise, fn, k) {
return promise.then(function() { return fn(k); });
}
function callGoogleMaps(k) {
return $q(function(resolve) {
//sample of a long-running operation inside loop...
GoogleMaps(hash[k][0], hash[k][1], function (x) {
var distance = x.rows[0].elements[0].distance.value;
distance = parseInt(distance / 1000);
AddDistance({ CityID1: hash[k][2], CityID2: $scope.CompanyCity.Id, DistanceKM: distance });
console.log(distance);
distances.push(distance);
resolve();
});
});
}
答案 1 :(得分:0)
你可以做类似下面的事情,但它不会保持循环:
var loopPromises = [];
var distanceList = [];
for (var k in hash) {
var deferred = $q.defer();
loopPromises.push(deferred.promise);
//sample of a long-running operation inside loop...
distanceList[k] = GoogleMaps(hash[k][0], hash[k][1], function (x) {
var distance = x.rows[0].elements[0].distance.value;
distance = parseInt(distance / 1000);
AddDistance({ CityID1: hash[k][2], CityID2: $scope.CompanyCity.Id, DistanceKM: distance });
console.log(distance);
//return distance;
deferred.resolve(distance);
});
};
$q.all(loopPromises).then(function () {
console.log('forEach loop completed. Do Something after it...');
//use the distanceList here
});
请注意,只要下一次迭代不依赖于前一次迭代,这种方法就可以正常工作。