我正在使用Geocodio,它是基于回调的地理编码。我有一个对象数组,每个对象都嵌套在其中。见下面的例子:
{
id: 0, title: "Half off all pizzas",
details:"Carry out only, all-day",
days: ["Monday", "Tuesday"],
restaurant: {
name: "Papa John's",
addressOne: "2937 Greenville Ave",
city: "Dallas",
state: "TX",
zip: 75206
}
}
我目前正在映射对象数组,以将每个餐馆的地址传递到地理编码功能。我想再向该对象添加一个名为location的属性,该对象将包含地理编码的结果。但是,在将函数的结果传递到对象之前,将返回该元素。见下文:
generateCoordinates (req, res, next) {
var newDeals = deals.map((cur, ind, arr) => {
location = new Promise (function(resolve, reject) {
geocodio.get('geocode', {q: `${cur.restaurant.addressOne},
${cur.restaurant.city}, ${cur.restaurant.state},
${cur.restaurant.zip}`}, function(err, response) {
if (err) {
reject(err)
throw err;
}
else {
var result = JSON.parse(response);
let obj = result.results[0].location;
// console.log(obj);
resolve(obj)
}
}
)}).then((obj) => {
cur.location = obj;
console.log(cur)
return cur;
})
return cur;
// console.log(newDeals)
})
res.status(200).send(newDeals)
},
我很有可能在这里滥用Promise构造函数。 .then中的console.log显示正确添加了location属性的每个元素,但响应和console.log(newDeals)将值显示为“Promise”。
如何设置数组中每个元素的location属性?
答案 0 :(得分:1)
是的,您不应该在异步回调中执行任何操作,而是拨打resolve
或reject
。特别是你不应该throw
!
return cur
并不完全有效,因为它发生在承诺解决之前。您需要从map
回调中返回承诺,然后使用Promise.all
等待阵列中的所有承诺。当最终完成时,只有这样您才能发送响应。在发生错误时也不要忘记发送适当的回复。
generateCoordinates (req, res, next) {
var newDeals = deals.map((cur, ind, arr) =>
new Promise((resolve, reject) => {
geocodio.get('geocode', {
q: `${cur.restaurant.addressOne},
${cur.restaurant.city}, ${cur.restaurant.state},
${cur.restaurant.zip}`
}, (err, response) => {
if (err) reject(err);
else resolve(response);
});
}).then(response => {
var result = JSON.parse(response);
let obj = result.results[0].location;
cur.location = obj;
console.log(cur)
return cur;
})
);
Promise.all(newDeals).then(results => {
res.status(200).send(results);
}, err => {
res.status(500); // or whatever
console.error(err);
});
}
答案 1 :(得分:0)
所以你想要返回一个值数组?你几乎拥有它,但你需要等待Promises解决。像这样的东西:
generateCoordinates (req, res, next) {
var newDeals = deals.map((cur, ind, arr) => {
return new Promise (function(resolve, reject) {
geocodio.get('geocode', {q: `${cur.restaurant.addressOne},
${cur.restaurant.city}, ${cur.restaurant.state},
${cur.restaurant.zip}`}, function(err, response) {
if (err) {
return reject(err);
}
else {
var result = JSON.parse(response);
let obj = result.results[0].location;
// console.log(obj);
resolve(obj)
}
}
)}).then((obj) => {
cur.location = obj;
console.log(cur)
return cur;
});
//newDeals is an array of promises at this point
Promise.all(newDeals).then(results => {
//results here is a value resolved from your promise above
return res.status(200).send(results)
}).catch(er r=> {
//handle errror
});
},
我正在做的是使用map来创建一个promises数组。然后使用Promise.all
等待承诺完成。无论您从then
内的map
区块返回的内容,最终都会以then
Promise.all
区块中的数组结尾。如果您拒绝任何承诺,它将自动在Promise.all