Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/74.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_Angular_Typescript_Rxjs_Ngrx - Fatal编程技术网

Javascript RxJS在订阅中订阅不同的观测值

Javascript RxJS在订阅中订阅不同的观测值,javascript,angular,typescript,rxjs,ngrx,Javascript,Angular,Typescript,Rxjs,Ngrx,我正在使用angular与ngrx store和RxJS存储和转换一些个人投资组合和适当的报价。当一个新的报价进来时,应该触发由web工作人员完成的计算。起初,我使用这段代码来达到预期的效果,但我注意到了一些缺陷 this.subs.sink = combineLatest([this.portfolio$, this.transactions$]) .pipe(sample(this.triggerCalculation$)) .subscribe(([portfolio, trans

我正在使用angular与ngrx store和RxJS存储和转换一些个人投资组合和适当的报价。当一个新的报价进来时,应该触发由web工作人员完成的计算。起初,我使用这段代码来达到预期的效果,但我注意到了一些缺陷

this.subs.sink = combineLatest([this.portfolio$, this.transactions$])
  .pipe(sample(this.triggerCalculation$))
  .subscribe(([portfolio, transactions]) => {
    if (!portfolio || !transactions || transactions.length === 0) {
      return
    }

    this.worker.postMessage({ message: 'calculate positions', payload: { portfolio, transactions } })

    this.subs.sink = combineLatest([
      this.store.select((s) => s.performance.positionMembers),
      this.store.select((s) => s.quotes.currencies),
    ]).subscribe(([positionMembers, currencies]) => {
      if (positionMembers.length === 0 || currencies === {}) {
        return
      }

      if (portfolio?.watchlist && positionMembers) {
        this.worker.postMessage({
          message: 'calculate total on static change'
        })

        portfolio.watchlist.all.forEach((a) => {
          if (positionMembers.includes(a._id)) {
            this.subs.sink = this.store
              .select((s) => s.quotes.quotes[a._id])
              .subscribe((q) => {
                if (q?.price) {
                  this.worker.postMessage({
                    message: 'calculate performance',
                    payload: {
                      id: a._id,
                      quote: q,
                      currency: a.currency,
                      currencies,
                      baseCurrency: portfolio.baseCurrency,
                    },
                  })
                }
              })
          }
        })
      }
    })
  })
我已经把它重构得更好了,至少我这么认为。我还改进了一些过滤功能:

this.subs.sink = this.transactions$
  .pipe(
    sample(this.triggerCalculation$),
    withLatestFrom(this.portfolio$),
    filter(([transactions, portfolio]) => portfolio?.watchlist && transactions?.length !== 0),
    tap(([transactions, portfolio]) => {
      this.worker.postMessage({ message: 'calculate positions', payload: { portfolio, transactions } })
    }),
    switchMap(([, portfolio]) => {
      return combineLatest([
        this.store.select((s) => s.performance.positionMembers),
        this.store.select((s) => s.quotes.currencies),
        of(portfolio),
      ]).pipe(filter(([members, currencies]) => !!members?.length && Object.keys(currencies).length !== 0))
    }),
    tap(() => {
      this.worker.postMessage({
        message: 'calculate total on static change',
      })
    })
  )
  .subscribe(([members, currencies, portfolio]) => {
    portfolio.watchlist.all.forEach((a) => {
      if (members.includes(a._id)) {
        this.subs.sink = this.store
          .select((s) => s.quotes.quotes[a._id])
          .pipe(filter((q) => !!q?.price))
          .subscribe((q) => {
            console.warn('subscription')
            this.worker.postMessage({
              message: 'calculate performance',
              payload: {
                id: a._id,
                quote: q,
                currency: a.currency,
                currencies,
                baseCurrency: portfolio.baseCurrency,
              },
            })
          })
      }
    })
  })
我的最后一个问题是如何摆脱内部订阅(公文包.watchlist.all.forEach的最后一个块),在这里我创建了多个订阅。目标是拥有与报价相同数量的订阅。每次收到新的引号时,我都会更改整个对象,因此订阅整个对象会更频繁地触发。请注意,每次外部订阅触发时都会创建订阅,因此可能会有无限多个内部订阅执行相同的操作。我只需要创建一次,但它们还应该反映导致新订阅的新报价


如果一些有经验的RxJS程序员能帮助我,我会非常高兴。

我从未发现一个有效的场景,其中一个订阅在另一个订阅中是一种有效的方法。每当您有一个场景需要在另一个场景中订阅时,请检查更高阶的可观察对象(如mergeMap、switchMap等)。看看这篇文章:我从来没有发现一个有效的场景,其中一个订阅在另一个订阅中是一种有效的方法。每当您有一个场景需要在另一个场景中订阅时,请检查更高阶的可观察对象(如mergeMap、switchMap等)。请看这篇文章: