Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/471.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript RxJS:承诺三个承诺,区分结果_Javascript_Promise_Rxjs - Fatal编程技术网

Javascript RxJS:承诺三个承诺,区分结果

Javascript RxJS:承诺三个承诺,区分结果,javascript,promise,rxjs,Javascript,Promise,Rxjs,我有三个承诺,Rest请求返回数据列表。 第三个列表中有前两个列表的引用(ID),因此当我拥有所有数据时,我希望将这些ID映射到相应的名称。 映射不是问题,我只是使用Lodash进行映射。 但问题是,在开始计算这一映射之前,要等待这三个承诺得到解决 我想使用concat(): 我的问题是onNext()将以随机顺序调用。也就是说,我不知道我在某个时候收到了哪个列表,从它包含的数据很难判断 有没有办法追踪哪些承诺产生了哪些清单?一种拉链?地图?concatMapObserver?我承认我还没有完全

我有三个承诺,Rest请求返回数据列表。
第三个列表中有前两个列表的引用(ID),因此当我拥有所有数据时,我希望将这些ID映射到相应的名称。
映射不是问题,我只是使用Lodash进行映射。
但问题是,在开始计算这一映射之前,要等待这三个承诺得到解决

我想使用
concat()

我的问题是
onNext()
将以随机顺序调用。也就是说,我不知道我在某个时候收到了哪个列表,从它包含的数据很难判断


有没有办法追踪哪些承诺产生了哪些清单?一种拉链?地图?concatMapObserver?我承认我还没有完全理解最后两个的用法…

如果这些是我们正在谈论的承诺,我想你可以看看
forkJoin
操作符。比照

然后,您可以使用类似于:

Rx.Observable.forkJoin(p1, p2, p3, function(p1,p2,p3){
/* your combining code here */
})

简而言之,
forkJoin
的语义类似于
RSVP。如果您知道承诺库RSVP,那么所有的

我今天早上做了一些实验,然后去看看是否有答案…:-)

你可以在

我发现,concat of observates将按照给定的顺序依次运行每个observate

  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); }
  );
给予

在第一个承诺达成之前,一系列承诺不会带来任何结果。然后它可以按照给定的顺序交付(即调用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); }
  );
给予

因此,基本上,concat尊重其论点的顺序,这可以作为一种方法来找出哪个请求发出了承诺结果。
在Ajax请求的情况下,承诺比可观察的更好,因为它们将被并行地请求,而不是顺序地请求(当然,除非您需要后者)

我尝试了@user3743222给出的解决方案,这是一个很好的解决方案。我更喜欢forkJoin,因为结果被显式地分配给参数,而不是依赖于顺序


您必须了解错误管理方面的差异:我发现concat将处理所有承诺,直到发现第一个错误。而forkJoin将不会处理任何错误。这是有道理的(一般来说,我们不能加入部分结果)。

谢谢。我发现了concat的真正工作原理(见我的答案),但我更喜欢forkJoin,它符合我的需求。我完全忽略了这个…:-)如果有人试图在Angular模式下工作,则不会,因为“complete”事件不会从http观察对象触发。对于一个类似的解决方案,我使用“combineLatest”来代替它。这是一个很好的实验。我还要补充一点,如果按顺序执行,得到的结果要比并行执行慢。
{"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
  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); }
  );
{"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
{"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