使用 RxJs 混合模型属性异步
Using RxJs to hydrate model properties async
我有一组模型,我想对其进行映射并对它们进行异步操作以合成该模型的 属性,然后最终订阅现在合成的原始模型列表。
例如。伪代码。需要一些帮助来填补空白 and/or 重构代码以使其更有意义
var people = [{
name: 'Jon',
location: 'New York, NY'
}, {
name: 'Joe',
location: null
}, {
name: 'Tom',
location: 'San Francisco, CA'
}];
var source = Rx.Observable.from(people);
source.map(function(person){
// Take current person.location and run it through geolocating service. I also need to throttle() the requests to the geolocating service.
//ex.
geocorder.geocode(person.location).then(function(result){
person.location = result;
});
return person;
})
.map(function(people){
//Now that model has been updated
person.save();
})
.subscribe(function(people){
//Once all the saving of people have completed. Show UI message;
})
主要技巧是让你的承诺实际上 return 修改后的人和 return 来自你的 map
操作的承诺。这为 Rx 提供了一些它可以等待知道地理定位何时完成的东西。
假设 person.save()
是同步的,我认为没有理由不在您获得地理定位结果后立即调用它。以下是您可以将其串在一起的方法,使用 merge(maxConcurrent) 来限制飞行中同时进行的地理定位请求的数量。
source
.map(function (person) {
// perform geolocating...
// return the geolocated person
// defer the call so that it is not actually performed until
// merge() subscribes to it.
return Rx.Observable.defer(function () {
return geocorder.geocode(person.location).then(function (r) {
person.location = r;
person.save(); // any reason not to save here?
return person;
});
});
})
.merge(2) // no more than 2 geocode requests outstanding at any given time
.toArray() // combine the individual people back into an array
.subscribe(function (people) {
// do something with the people
});
我认为flatMap
aka selectMany
可以胜任。
Rx.Observable.from(people)
.flatMap(function(person){
return geocorder.geocode(person.location).then(function(result){
person.location = result;
person.save();
});
})
.subscribe(function(people){
// ...
});
我想这相当于 defer
和 toArray
的组合。
我有一组模型,我想对其进行映射并对它们进行异步操作以合成该模型的 属性,然后最终订阅现在合成的原始模型列表。
例如。伪代码。需要一些帮助来填补空白 and/or 重构代码以使其更有意义
var people = [{
name: 'Jon',
location: 'New York, NY'
}, {
name: 'Joe',
location: null
}, {
name: 'Tom',
location: 'San Francisco, CA'
}];
var source = Rx.Observable.from(people);
source.map(function(person){
// Take current person.location and run it through geolocating service. I also need to throttle() the requests to the geolocating service.
//ex.
geocorder.geocode(person.location).then(function(result){
person.location = result;
});
return person;
})
.map(function(people){
//Now that model has been updated
person.save();
})
.subscribe(function(people){
//Once all the saving of people have completed. Show UI message;
})
主要技巧是让你的承诺实际上 return 修改后的人和 return 来自你的 map
操作的承诺。这为 Rx 提供了一些它可以等待知道地理定位何时完成的东西。
假设 person.save()
是同步的,我认为没有理由不在您获得地理定位结果后立即调用它。以下是您可以将其串在一起的方法,使用 merge(maxConcurrent) 来限制飞行中同时进行的地理定位请求的数量。
source
.map(function (person) {
// perform geolocating...
// return the geolocated person
// defer the call so that it is not actually performed until
// merge() subscribes to it.
return Rx.Observable.defer(function () {
return geocorder.geocode(person.location).then(function (r) {
person.location = r;
person.save(); // any reason not to save here?
return person;
});
});
})
.merge(2) // no more than 2 geocode requests outstanding at any given time
.toArray() // combine the individual people back into an array
.subscribe(function (people) {
// do something with the people
});
我认为flatMap
aka selectMany
可以胜任。
Rx.Observable.from(people)
.flatMap(function(person){
return geocorder.geocode(person.location).then(function(result){
person.location = result;
person.save();
});
})
.subscribe(function(people){
// ...
});
我想这相当于 defer
和 toArray
的组合。