使用 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){
    // ...
});

See here

我想这相当于 defertoArray 的组合。