问题描述
我试图在一个循环内两次调用一次Web API,然后等到webAPI返回后,再将返回的值作为子数组推入更大的数组中。这是我的代码:
var latlngPairs = [];
function extractLatLongPairs(jsonobj){
for(var i = 0; i<10; i++){
let promises = [googlePlace(jsonobj[i]['From LID']),googlePlace(jsonobj[i]['To LID'])];
Promise.all(promises).then((results) => {
var temp2 = [results[0],results[1]];
latlngPairs.push(temp2);
console.log(latlngPairs);
});
}
}
function googlePlace(airport){
https.get('https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=' + airport + '&inputtype=textquery&fields=geometry',(resp) => {
let data = '';
// A chunk of data has been recieved.
resp.on('data',(chunk) => {
data += chunk;
});
//All data is returned
resp.on('end',() => {
data = JSON.parse(data);
let obj = {
name: airport,location: data.candidates[0].geometry.location
};
console.log('latlong should print after this');
return Promise.resolve(obj);
});
}).on("error",(err) => {
console.log("Error: " + err.message);
});
}
我希望在打印latlngPairs之前先打印console.log(“ latlong应该在此之后打印”)。由于顺序相反,因此latlngPairs会填充具有未定义值的子数组。输出类似于:
[
[ undefined,undefined ],[ undefined,undefined ]
]
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
latlong should print after this
为了清楚起见,我要实现的顺序是“此后应该打印latlong”,然后是“ [[obj,obj],[obj,obj]]”。我认为我对Promise.all的运作方式必须有一些根本的误解,不胜感激!
解决方法
您需要使您的googlePlace
函数实际上返回一个Promise:
function googlePlace(airport) {
// notice the new Promise here
return new Promise((resolve,reject) => {
https
.get(
"https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=" +
airport +
"&inputtype=textquery&fields=geometry",(resp) => {
let data = "";
// A chunk of data has been recieved.
resp.on("data",(chunk) => {
data += chunk;
});
//All data is returned
resp.on("end",() => {
data = JSON.parse(data);
let obj = {
name: airport,location: data.candidates[0].geometry.location,};
console.log("latlong should print after this");
// notice the resolve here
resolve(obj);
});
}
)
.on("error",(err) => {
console.log("Error: " + err.message);
reject(err.message);
});
});
}