我使用googles api获得3个字段, 名称评级和地点评论。由于地方审查使用另一个api调用我创建它作为一个函数来获取我的place_review中的数据。
response.results.forEach((entry)=>{
var restaurantName = {
"name" : entry.name,
"rating" : entry.rating,
"place_review" : placeReview(entry.place_id)
}
arr.push(restaurantName);
console.log(restaurantName);// shows only name and rating
});
额外功能
function placeReview(place_id){
console.log(place_id) // i see all place id via forloop.
googlePlaces.placeDetailsRequest({placeid: place_id},function(error,response){
if (error) throw error;
return response.result.reviews[0].text;
});
}
当我运行代码时,我得到name : somename
,rating : 4.5
和place_review : null
我以为forloop会调用该函数,函数的返回会将字符串追加到"place_review"
,不知道我做错了什么。
答案 0 :(得分:0)
placeDetailsRequest
api是异步的,这意味着它已启动但不会立即完成。因此,行:
return response.result.reviews[0].text;
没有意义,因为没有什么可以回归。
您的console.log(restaurantName);
将在请求完成之前运行,因此您只能获得“未定义”。
要解决这个问题,你需要做一些更复杂的事情(假设,现在Promises是你不熟悉的东西,但这通常是人们对异步编程方式感到满意的方式作品):
response.results.forEach((entry)=>{
var restaurantName = {
"name" : entry.name,
"rating" : entry.rating,
"place_review" : undefined // will be filled in later
}
placeReview(entry.place_id, restaurantName);
});
function placeReview(place_id, obj){
console.log(place_id) // i see all place id via forloop.
googlePlaces.placeDetailsRequest({placeid: place_id},function(error,response){
if (error) throw error;
obj.place_review = response.result.reviews[0].text;
console.log(obj);
});
}
当然,您只会在每个请求完成时看到控制台结果。
这使用一种称为“回调”的技术来管理仅在以后可用的信息。在线和SO上有很多关于此的信息。
这是一个可以运行以查看该技术的版本 - 与上述非常相似但是硬连接了一些数据。
var list = [
{ name: 'Aaron', rating: '14', place_id: 21 },
{ name: 'Brad', rating: '33', place_id: 33 }
];
list.forEach(function (entry) {
var restaurantName = {
"name" : entry.name,
"rating" : entry.rating,
"place_review" : undefined // will be filled in later
};
placeReview(entry.place_id, restaurantName);
});
function placeDetailsRequest(idObj, cb) {
setTimeout(function() {
var result = (idObj.placeid === 21) ? 'def' : 'abc';
cb(null, { result: { reviews: [{ text: result}]}});
}, 2000);
}
function placeReview(place_id, obj) {
console.log(place_id); // i see all place id via for loop.
placeDetailsRequest( { placeid: place_id }, function(error,response){
if (error) throw error;
obj.place_review = response.result.reviews[0].text;
console.log(obj);
});
}
进一步编辑以显示承诺解决方案:
var list = [
{ name: 'Aaron', rating: '14', place_id: 21 },
{ name: 'Brad', rating: '33', place_id: 33 }
];
var allPromises = list.map(function (entry) {
var restaurantName = {
"name" : entry.name,
"rating" : entry.rating,
"place_review" : undefined // will be filled in later
};
return placeReview(entry.place_id, restaurantName);
});
Promise.all(allPromises)
.then(results => console.log(results))
.catch(error => console.log(error));
function placeReview(place_id, obj) {
return new Promise((resolve, reject) => {
// Here's where you would do your google api call to placeDetailsRequest
// if error then reject the promise, otherwise resolve it with your results
//googlePlaces.placeDetailsRequest({placeid: place_id},function(error,response){
// if (error) {
// reject(error);
// } else {
// obj.place_review = response.result.reviews[0].text;
// resolve(obj);
// }
//});
// simulating with delayed response
setTimeout(() => {
var result = (place_id === 21) ? 'def' : 'abc';
obj.place_review = result;
resolve(obj);
}, 2000);
});
}
还有其他方法可以解决这个问题,但在这个解决方案中,我正在使用已完成的对象解决这个问题。 Promise.all()函数then
要么显示成功结果,要么catch
会显示错误。
答案 1 :(得分:-1)
<强>承诺强>
您可以使用Q在您的地点审核功能中实施承诺:
function placeReview (place_id) {
var deferred = Q.defer();
googlePlaces.placeDetailsRequest({placeid: place_id},function(error,response){
if (error) deferred.reject(err);
else deferred.resolve(response.result.reviews[0].text);
});
return deferred.promise // the promise is returned
}
然后您可以在处理逻辑中调用该函数,如下所示:
response.results.forEach((entry)=>{
placeReview(entity.place_id).then(function(text) {
var restaurantName = {
"name" : entry.name,
"rating" : entry.rating,
"place_review" : text
}
arr.push(restaurantName);
console.log(restaurantName);// shows only name and rating
});
});
在您完成对API的调用之前,您不会推送餐厅的详细信息。
异步选项
您可以使用async协调来电:
每个条目都会执行一次此函数:
function placeReview(entry, callback){
console.log(entry.place_id)
googlePlaces.placeDetailsRequest({entry.placeid: place_id},function(error,response){
if (error) throw error;
//this call back retrives the restaurant entity that async stack in a list
callback(null,{
"name" : entry.name,
"rating" : entry.rating,
"place_review" : response.result.reviews[0].text
});
});
}
然后你要求async迭代你的结果数组并为每一个执行placeReview。 Async会在数组中收集结果:
async.map(response.results, placeReview, function(err, results) {
// results will have the results of all 2
console.log(results); //this is your array of restaurants
});