我正在尝试获取多个Google商家信息的数据,然后为地图上的每个地点绘制标记。我正在尝试使用promises等到更新地图之前检索到每个地方的数据。这就是我所拥有的:
var service = new google.maps.places.PlacesService(map),
promises = [],
promise = '',
searchCallback = function(results, status) {
if(status == google.maps.places.PlacesServiceStatus.OK) {
for(var i = 0; i < results.length; i++) {
var place = results[i];
// this works
console.log(place);
// resolve the promise
promise.resolve(place);
}
}
}
$('li').each(function(index) {
promise = $.Deferred(),
var lng = $(this).attr('data-longitude'),
lat = $(this).attr('data-latitude'),
name = $(this).text(),
latLng = new google.maps.LatLng(lat, lng),
request = {
location: latLng,
radius: '500',
query: name
};
// push promise into array
promises.push(promise);
// get data about place
service.textSearch(request, searchCallback);
}
// when all promises are complete
$.when.apply($, promises).then(function(data) {
console.log(data);
});
我的PlacesService
工作正常。我可以console.log(place)
我看到Google返回的对象,但是当我在console.log(data)
回调中尝试$.when
时,data
会返回undefined。看来我的承诺不能正常运作。我错过了什么?
答案 0 :(得分:0)
用promise
作为外部var:
promise
。$('li').each()
循环后,Deferred将是循环中分配的 last 。service.textSearch()
将导致最后一个承诺解决。因此,promises
数组将正确包含所有生成的Deferred,但只会解析最后一个。所有其他Derferreds将保持&#34;待定&#34;并且$.when.apply($, promises)
永远无法解决。
此类问题的推荐策略是:
对于错误处理,有一个设计选择。你可以:
在这种情况下,第二种选择似乎是最合适的。
var service = new google.maps.places.PlacesService(map);
// Promisify service.textSearch() as service.textSearchAsync()
// (lowest level)
service.textSearchAsync = function(options) {
return $.Deferred(function(dfrd) {
service.textSearch(options, function(results, status) {
if(status == google.maps.places.PlacesServiceStatus.OK) {
promise.resolve(results);
} else {
promise.reject(new Error(status));
}
});
}).promise();
};
// Map the 'li' elements to an array of promises, exploiting the low level utility.
// (intermediate level)
var promises = $('li').map(function(index) {
return service.textSearchAsync({
location: new google.maps.LatLng($(this).data('latitude'), $(this).data('longitude')),
radius: '500',
query: $(this).text()
}).then(null, function(error) {
console.error(error);
return $.when([]); // error recovery (deliver an empty array) such that any individual failure of `service.textSearch()` doesn't scupper the whole endeavour.
});
}).get();// .get() is necessary to remove the jQuery wrapper returned by $('li').map()
// Aggregate the promises then handle the data gathered
// (highest level)
$.when.apply($, promises).then(function() {
console.log(arguments); // jQuery.when() delivers data 'spread' into the arguments of its .then() callback
var i, j, results, place;
for(i=0; i<arguments.length; i++) {
results = arguments[i];
for(j=0; j<results.length; j++) {
place = results[j];
console.log(place);
// now plot `place` as a marker on the map.
}
}
});