【问题标题】:RxJS, Observable, how to preserve value and switch map to another oneRxJS,Observable,如何保存值并将映射切换到另一个
【发布时间】:2018-03-05 23:45:14
【问题描述】:
// ticker$ will update every 3s
// showHand$ will only triger after user click button
// I would like to take last ticker price as user order price when user click button

let lastPrice: number;

this.ticker$
  // What I am doing now is preserve value to vairable here.
  .do(ticker => lastPrice = ticker.closePrice)
  .switchMap(() => this.showHand$)
  .subscribe(showHand => {
     // use value here
     this.order.price = lastPrice;
     this.order.amount = showHand.amount;
     this.order.type = showHand.type;

     this.submit();
  });

关于如何在没有像上面那样的一个 line 变量的情况下一起保存 value 和 switch map 的任何问题?

【问题讨论】:

  • 请考虑将接受的答案更改为 Cameron 发布的结果选择器解决方案。无需使用其他运算符,withLatestFrom 有一些注意事项。

标签: javascript angular typescript rxjs observable


【解决方案1】:

我认为这是运营商

this.showHand$.take(1)
  .withLatestFrom(this.ticker$)
  .subscribe(([showHand, ticker]) => {
    this.order.price = ticker.closePrice;
    this.order.amount = showHand.amount;
    this.order.type = showHand.type;
    this.submit();      
  });

注意,take(1) 将关闭订阅,但如果您希望用户能够多次按下按钮,请将订阅保存为 const 并在完成后取消订阅。

【讨论】:

  • take(1) 是做什么的?
  • take(n) 限制来自 showHand$ 的项目数,并在 n 个项目后发出 complete()。对此的完整应该会自动停止订阅。
【解决方案2】:

您需要的行为已经可以通过 SwitchMap 的重载和用于每个 (outerValue,innerValue) 组合的 selectorFunc 实现:

this.ticker$
  .switchMap(
    () => this.showHand$,
    (tickerValue, switchMap) => tickerValue
  )
  .subscribe(showHand => { });

【讨论】:

  • 有人应该写一篇关于这个 resultSelectorFunction 的文章
  • resultSelector 自 rxjs 6 起已弃用
【解决方案3】:

结果选择器功能在版本 6 中已弃用,将在版本 7 中删除。

来自文档:

https://github.com/ReactiveX/rxjs/blob/master/docs_app/content/guide/v6/migration.md#result-selectors

使用 resultSelector (v5.x)

source.pipe(
 switchMap(fn1, fn2)
)

没有 resultSelector 的相同功能,通过内部地图实现

source.pipe(
 switchMap((a, i) => fn1(a, i).pipe(
   map((b, ii) => fn2(a, b, i, ii))
 )
)

【讨论】:

  • 这应该是公认的答案。 withLatestFrom() 在延迟订阅时有一些注意事项,这是该解决方案所没有的。
  • 这里的第二个例子(switchMap 和内部map)对我来说非常有用!
【解决方案4】:

有一个小技巧可以实现这一点——基本上你在 switchmap 中有一个全新的 observable,并且这个 observable 可以访问传递给 switchmap 函数的值。您可以在内部映射中使用此值来保留该值。

this.ticker$
  .switchMap(ticker => this.showHand$.pipe(map( (hand) => { ticker,hand } )))
  .subscribe( obj => {
     // use value here
     this.order.price = obj.ticker;
     this.order.amount = obj.hand.amount;
     this.order.type = obj.hand.type;

     this.submit();
  });

【讨论】:

    猜你喜欢
    • 2022-01-08
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多