Google maps 在非异步上下文中使用回调
我有一个名为“Google maps 在非异步上下文中使用回调,google-maps,ember.js,Google Maps,Ember.js,我有一个名为“getGmapsDistance()”的服务。在这里,我使用谷歌地图api获取起点和终点之间的距离 export default Ember.Service.extend({ getShortestDistanceInMeters: function(location) { var service = new google.maps.DistanceMatrixService(); service.getDistanceMatrix({ ...
getGmapsDistance()
”的服务。在这里,我使用谷歌地图api获取起点和终点之间的距离
export default Ember.Service.extend({
getShortestDistanceInMeters: function(location) {
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
...
}, this.callback); //<<<<<< !!!
},
callback: function(response, status) {
....
}
});
locationsNearby: Ember.computed('locations', function() {
//...
var filteredResult = [];
locations.forEach(function(locat) {
if (this.get('distanceService').getShortestDistanceInMeters(locat) <= maxDistance) {
filteredResult.pushObject(locat);
}
});
return filteredResult;
})
导出默认Ember.Service.extend({
getShortestDistanceInMeters:函数(位置){
var service=new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
...
},this.callback);//您不能使异步调用同步!这是javascript语言的一个限制,必须理解!javascript只有一个线程,因此不能由库或其他程序更改
处理回调的新方法是承诺。
你真的应该结账!
这是你读过的最漂亮的说明书之一
Ember大量使用承诺!例如,routesmodel
hook在继续转换之前等待承诺的解析
在您的情况下,您希望在承诺解析时更新computed属性。因为余烬数据经常导致这种情况发生,所以它们提供了两个奇特的类:PromiseObject和PromiseArray。依赖于返回PromiseObject/数组的computed属性的computed属性将在承诺解析时重新计算:
locationsNearby: Ember.computed('locations', {
get() {
let promise = Ember.RSVP.all(this.get('locations').map(location => Ember.RSVP.hash(({
location,
distance: this.get('distanceService').getShortestDistanceInMeters(location)
})))).then(hashs => hashs.filter(hash => hash.distance <= maxDistance).map(hash => hash.location));
return DS.PromiseArray.create({promise});
}
})
然后,我对所有这些函数使用RSVP.hash
,以获得一个承诺数组,该数组将解析为一个具有距离和位置的哈希数组:
let hashPromiseArr = locationsWithDistancePromise.map(h => Ember.RSVP.hash(h));
现在,我使用Ember.RSVP.all
获得一个承诺,该承诺将解析为一个包含位置和距离的哈希数组:
let locationsWithDistancePromise = this.get('locations').map(location => {
distance: this.get('distanceService').getShortestDistanceInMeters(location),
location
})
let hashArrPromise = Ember.RSVP.all(hashPromiseArr);
最后我。然后在promise上,并过滤附近的位置。我还将哈希映射到一个位置数组
let promise = hashArrPromise.then(hashs => {
return hashs.filter(hash => hash.distance <= maxDistance)
.map(hash => hash.location);
});
您可以使用{{{each}}
从把手循环这个计算属性,或者在另一个计算属性中使用它:
allNearbyLocations: Ember.computed('locationsNearby.[]', {
get() {
return this.get('locationsNearby').toArray().join(' - ');
}
}
当然,您需要重写getshortdistanceinmeters
,以便它返回一个承诺:
getShortestDistanceInMeters(location) {
var service = new google.maps.DistanceMatrixService();
return new Ember.RSVP.Promise((resolve, reject) => {
service.getDistanceMatrix({
//...
}, (response, status) => {
if(status.error) {
reject(response);
} else {
resolve(response);
}
});
});
}
您不能使异步调用同步!这是一个javascript语言限制,必须理解!javascript只有一个线程,因此不能由库更改
处理回调的新方法是承诺。
你真的应该结账!
这是你读过的最漂亮的说明书之一
Ember大量使用承诺!例如,routesmodel
hook在继续转换之前等待承诺的解析
在您的情况下,您希望在承诺解析时更新computed属性。因为余烬数据经常导致这种情况发生,所以它们提供了两个奇特的类:PromiseObject和PromiseArray。依赖于返回PromiseObject/数组的computed属性的computed属性将在承诺解析时重新计算:
locationsNearby: Ember.computed('locations', {
get() {
let promise = Ember.RSVP.all(this.get('locations').map(location => Ember.RSVP.hash(({
location,
distance: this.get('distanceService').getShortestDistanceInMeters(location)
})))).then(hashs => hashs.filter(hash => hash.distance <= maxDistance).map(hash => hash.location));
return DS.PromiseArray.create({promise});
}
})
然后,我对所有这些函数使用RSVP.hash
,以获得一个承诺数组,该数组将解析为一个具有距离和位置的哈希数组:
let hashPromiseArr = locationsWithDistancePromise.map(h => Ember.RSVP.hash(h));
现在,我使用Ember.RSVP.all
获得一个承诺,该承诺将解析为一个包含位置和距离的哈希数组:
let locationsWithDistancePromise = this.get('locations').map(location => {
distance: this.get('distanceService').getShortestDistanceInMeters(location),
location
})
let hashArrPromise = Ember.RSVP.all(hashPromiseArr);
最后我。然后在promise上,并过滤附近的位置。我还将哈希映射到一个位置数组
let promise = hashArrPromise.then(hashs => {
return hashs.filter(hash => hash.distance <= maxDistance)
.map(hash => hash.location);
});
您可以使用{{{each}}
从把手循环这个计算属性,或者在另一个计算属性中使用它:
allNearbyLocations: Ember.computed('locationsNearby.[]', {
get() {
return this.get('locationsNearby').toArray().join(' - ');
}
}
当然,您需要重写getshortdistanceinmeters
,以便它返回一个承诺:
getShortestDistanceInMeters(location) {
var service = new google.maps.DistanceMatrixService();
return new Ember.RSVP.Promise((resolve, reject) => {
service.getDistanceMatrix({
//...
}, (response, status) => {
if(status.error) {
reject(response);
} else {
resolve(response);
}
});
});
}
您可以从getShortestDistanceInMeters
方法返回承诺,签出您可以从getShortestDistanceInMeters
方法返回承诺,签出感谢@Lux的这种大方法,但我认为它不起作用:据我所知,getShortestDistanceInMeters函数没有“等待”机制(因为它会立即返回“nothing”,并且只有异步回调函数会从google得到答案)。因此,在您的解决方案中,承诺将立即实现,因为它的返回将不包括api请求的结果。对吗?我已编辑了答案。当然,您必须重写GetShortDistanceInMeters
,因此它将返回一个承诺。非常感谢,到目前为止这非常有用!但它仍然无法100%工作。在我的回答中,console.out正在工作,但不在模板中。请查看以下要点:您能再帮我处理最后一部分吗?:)第21行缺少return
。或者省略花括号。因为x=>1
返回1,并且与x=>{return 1}
相同,但是x=>{1}
将返回未定义的!并且您需要PromiseArray
来制作一个合适的数组,以便在把手模板中循环。PromiseArray首先是一个空数组,稍后将更新为已解析的数组。先生,您太棒了!非常感谢@Lux!感谢@Lux的这种大方法,但我认为它是有效的nt工作:据我所知,他们的getShortestDistanceInMeters函数没有“等待”机制(因为它会立即返回“nothing”,只有异步回调函数会从google得到答案)。因此,在您的解决方案中,承诺将立即实现,因为它的返回将不包括api请求的结果。对吗?我已编辑了答案。当然,您必须重写GetShortDistanceInMeters
,因此它将返回一个承诺。非常感谢,到目前为止这非常有用!但它仍然无法100%工作。在我的回答中,console.out正在工作,但不在模板中。请查看以下要点:您能再帮我处理最后一部分吗?:)第21行缺少return
。或者省略花括号。因为x=>1
返回1,并且与x=>{return 1}
相同,但是x=>{1}
将返回未定义的!并且您需要PromiseArray
来创建一个可在han中循环的宜人数组