Phi*_*Lho 8 javascript promise rxjs
我有三个承诺,Rest请求返回数据列表.
第三个对前两个列表有引用(ids),所以我想在拥有所有数据时将这些id映射到相应的名称.
映射不是问题,我只是使用Lodash.
但问题是在开始计算这个映射之前等待三个promises解决.
我想出来使用concat()
:
Rx.Observable.concat(p1, p2, p3).subscribe(
function onNext(list)
{
// Assign the list to the corresponding variable in the scope
},
function onError(e)
{
// Notify of error
},
function onCompleted()
{
// Do the mapping
}
);
Run Code Online (Sandbox Code Playgroud)
我的问题是onNext()
将以随机顺序调用.IE浏览器.我不知道在某些时候我收到了哪个列表,并且很难从它包含的数据中分辨出来.
有没有办法跟踪哪些承诺产生哪个列表?拉链?concatMap?concatMapObserver?我承认我还没有完全理解最后两个的用法......
use*_*222 10
如果这些是我们正在谈论的承诺,我想你可以看看forkJoin
运营商.参看 https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/forkjoin.md,http://xgrommx.github.io/rx-book/content/observable/observable_methods/ forkjoin.html
然后你可以有类似的东西:
Rx.Observable.forkJoin(p1, p2, p3, function(p1,p2,p3){
/* your combining code here */
})
Run Code Online (Sandbox Code Playgroud)
简而言之,forkJoin
语义类似于RSVP.all
你知道promises库RSVP的语义.
今天早上我做了一些实验,然后再看我是否有答案... :-)
您可以在http://plnkr.co/edit/3Xczzw上看到它们
我发现可观察物的联合将按给定顺序依次运行每个可观察物。
var o1 = Rx.Observable.interval(1500).take(1).map(function (i) { return { n: i, id: 'First', ts: Date.now() - reference }});
var o2 = Rx.Observable.interval(1000).take(2).map(function (i) { return { n: i, id: 'Second', ts: Date.now() - reference }});
var o3 = Rx.Observable.interval(2000).take(1).map(function (i) { return { n: i, id: 'Third', ts: Date.now() - reference }});
// Alternative
var oa = Rx.Observable.timer(1200).map(function (i) { return { n: i, id: 'Alternative', ts: Date.now() - reference }});
Rx.Observable.concat(o1, o2, o3, oa).subscribe(
function onNext(v) { v.timestamp = Date.now() - reference; showObject(v); },
function onError(e) { var ts = Date.now() - reference; showHTML("Error " + JSON.stringify(e) + " at " + ts); },
function onCompleted() { var ts = Date.now() - reference; showHTML("Completed at " + ts); }
);
Run Code Online (Sandbox Code Playgroud)
给
{"n":0,"id":"First","ts":1503,"timestamp":1503}
{"n":0,"id":"Second","ts":2504,"timestamp":2504}
{"n":1,"id":"Second","ts":3505,"timestamp":3505}
{"n":0,"id":"Third","ts":5506,"timestamp":5506}
{"n":0,"id":"Alternative","ts":6708,"timestamp":6708}
Completed at 6708
Run Code Online (Sandbox Code Playgroud)
在第一个诺言化解之前,一连串的诺言不会交付任何东西。然后,它可以按照给定的顺序交付(即调用onNext)其他已解决的承诺。然后可以等待下一个承诺(如果还有),等等。
var p1 = promiseInTime(1500, { id: 'First'});
var p2 = promiseInTime(1000, { id: 'Second' });
var p3 = promiseInTime(2000, { id: 'Third' });
var pa = promiseInTime(1200, { id: 'Failed? ' + !!withFailure }, withFailure);
Rx.Observable.concat(p1, p2, p3, pa).subscribe(
function onNext(v) { v.timestamp = Date.now() - reference; showObject(v); },
function onError(e) { var ts = Date.now() - reference; showHTML("Error " + JSON.stringify(e) + " at " + ts); },
function onCompleted() { var ts = Date.now() - reference; showHTML("Completed at " + ts); }
);
Run Code Online (Sandbox Code Playgroud)
给
{"id":"First","promiseTimeout":1500,"timestamp":1501}
{"id":"Second","promiseTimeout":1000,"timestamp":1506}
{"id":"Third","promiseTimeout":2000,"timestamp":2001}
Error {"id":"Failed? true","promiseTimeout":1201} at 2004
Run Code Online (Sandbox Code Playgroud)
要么
{"id":"First","promiseTimeout":1500,"timestamp":1501}
{"id":"Second","promiseTimeout":1000,"timestamp":1503}
{"id":"Third","promiseTimeout":2000,"timestamp":2000}
{"id":"Failed? false","promiseTimeout":1201,"timestamp":2004}
Completed at 2004
Run Code Online (Sandbox Code Playgroud)
因此,基本上,concat尊重其参数的顺序,这可以作为一种方法来查找哪个请求发出了承诺结果。
在Ajax请求的情况下,与可观察对象相比,可兑现的承诺更好,因为它们是并行而不是顺序地请求的(当然,除非您需要后者)。
我尝试了@ user3743222提供的解决方案,这是一个不错的解决方案。我更喜欢forkJoin,因为将结果显式分配给参数,而不是依赖顺序。
您必须意识到错误管理方面的差异:我发现concat将处理所有的promise,直到找到第一个错误为止。而forkJoin不会处理任何承诺错误之一。这是有道理的(通常,我们不能加入部分结果)。
归档时间: |
|
查看次数: |
9655 次 |
最近记录: |