尝试批量处理Google ElevationService的请求(并在Stack Overflow上留下一些问题)我现在指向Promise对象,这对我来说是全新的。
假设我有一个循环运行4次,或在另一种情况下运行7次,或在另一种情况下运行2次;我将如何在该循环中实现Promise aproach?此时此设置是为了尝试获取250 LatLng的高程数据,这是给定Google Maps DirectionsResponse的时间。
var currentBatch = 0;
while(currentBatch < totalElevationBatches) {
getRouteElevationChartDataBatch(currentBatch, batchSize);
currentBatch++;
}
function getRouteElevationChartDataBatch(batch, batchSize) {
return new Promise(function(resolve, reject) {
var elevator = new google.maps.ElevationService();
var thisBatchPath = [];
for (var j = batch * batchSize; j < batch * batchSize + batchSize; j++) {
if (j < directions.routes[0].overview_path.length) {
thisBatchPath.push(directions.routes[0].overview_path[j]);
} else {
break;
}
}
elevator.getElevationAlongPath({
path: thisBatchPath,
samples: 256
}, function (elevations, status) {
if (status != google.maps.ElevationStatus.OK) {
reject(status);
}
routeElevations = routeElevations.concat(elevations);
});
});
}
但是这些调用仍然是异步执行的,因为它们没有与.then()
方法链接。如何链接可变数量的链并知道何时完成?对不起,如果这是一个完全愚蠢的问题;但在查阅文档(here和here)
答案 0 :(得分:1)
我认为使用超时不会提供有效的解决方案,一种简单的方法是将每个promise调用添加到单个promise链的'then',例如:
let promise = Promise.resolve(), // initialize promise chain
someArray = [ ... ];
for(let i=0;i<someArray.length;i++)
promise = promise.then(() => someCall(someArray[i]))
所以你的代码可以修改为下面的代码:(我最后加了一个解决方案,就像Jaromanda X说的那样)
var currentBatch = 0, promise = Promise.resolve();
while(currentBatch < totalElevationBatches) {
promise = addToChain(promise, currentBatch, batchSize);
currentBatch++;
}
promise.then(...) // write code inside then that would handle once all the batches are processed
function getRouteElevationChartDataBatch(batch, batchSize) {
return new Promise(function(resolve, reject) {
var elevator = new google.maps.ElevationService();
var thisBatchPath = [];
for (var j = batch * batchSize; j < batch * batchSize + batchSize; j++) {
if (j < directions.routes[0].overview_path.length) {
thisBatchPath.push(directions.routes[0].overview_path[j]);
} else {
break;
}
}
elevator.getElevationAlongPath({
path: thisBatchPath,
samples: 256
}, function (elevations, status) {
if (status != google.maps.ElevationStatus.OK) {
reject(status);
}
routeElevations = routeElevations.concat(elevations);
resolve();
});
});
}
function addToChain(chain, batch, batchSize){
return chain.then(function(){
return getRouteElevationChartDataBatch(batch, batchSize);
});
}