【问题标题】:Multiple subscriptions without recalculate common part无需重新计算公共部分的多个订阅
【发布时间】:2019-07-11 13:09:28
【问题描述】:
const ex = ajax.getJSON('https://httpbin.org/get?a=24');
ex.pipe(pluck('args')).subscribe(x => console.log('Args: ', x));
ex.pipe(pluck('headers')).subscribe(x => console.log('Headers: ', x));

上面的代码(StackBlitz)为每个订阅启动两个 ajax 请求。

为所有现有订阅仅启动一个可观察管道/链的正确方法是什么?

我可以通过为 ajax(StackBlitz) 引入 Promise 来实现:

const p = new Promise(resolve => {
  ajax.getJSON('https://httpbin.org/get?a=24')
  .subscribe(res => resolve(res));
});

from(p).pipe(pluck('args')).subscribe(x => console.log('Args: ', x));
from(p).pipe(pluck('headers')).subscribe(x => console.log('Headers: ', x));

但我相信一定有更方便的方式。

【问题讨论】:

标签: ajax angular rxjs


【解决方案1】:

来自 cmets 的shareReplay 解决了我的问题:

const src = tag => of(42)
  .pipe(tap(_ => console.info(tag, 'source called')));

const ex = src('shareReplay').pipe(
  shareReplay(1)
);

ex.subscribe(x => console.log('sa:', x));
ex.subscribe(x => console.log('sb:', x));
shareReplay source called
sa: 42
sb: 42

Full demo

【讨论】:

  • 这也是我在这种情况下的 goto 运算符 :)
【解决方案2】:

您可以为此使用publish operator

const ex = ajax.getJSON('https://httpbin.org/get?a=24').pipe(publish());
ex.pipe(pluck('args')).subscribe(x => console.log('Args: ', x));
ex.pipe(pluck('headers')).subscribe(x => console.log('Headers: ', x));
ex.connect();

ajax 请求只会发生一次,并且仅在调用connect() 方法之后(stackblitz demo)。

【讨论】:

  • 连接后订阅完成后收不到结果?
  • 哦,我认为您在代码的不同位置获取了这两个部分(参数和标题),嗯?在这种情况下,imo,也许您应该创建一个额外的 ReplaySubject 只是为了从后端重新发送最后抓取的结果。但如果我有好消息,我会做一些研究并回来。
  • 我的问题的重要部分 - 我应该能够在收到实际数据之前和之后订阅它。第一个订阅应该启动数据获取,其他人等待它或立即接收它,如果已经获取。为了清楚起见,我在我的问题中添加了 Promise 实现。可能是shareReplay cmets 的建议会很有用,我现在读了。
猜你喜欢
  • 2016-07-14
  • 1970-01-01
  • 1970-01-01
  • 2021-02-23
  • 2021-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多