【问题标题】:rxjs: conditional take numberrxjs:条件取数
【发布时间】:2021-01-31 21:25:56
【问题描述】:

我有这个函数,它返回一个可观察的,它发出一个 deviceId 及其相关的 MediaStream:

 private getStreamToDeviceId(deviceKind: "audioinput" | "videoinput") {
    return from(navigator.mediaDevices.enumerateDevices()).pipe(
      map((devices) =>
        devices
          .filter((device) => device.kind === deviceKind)
          .map((device) => device.deviceId)
      ),
      take(1),
      concatMap((deviceIds) => of(...deviceIds)),
      concatMap((deviceId) =>
        zip(
          of(deviceId),
          from(
            navigator.mediaDevices.getUserMedia({
              audio: deviceKind === "audioinput" ? { deviceId } : false,
              video: deviceKind === "videoinput" ? { deviceId } : false,
            })
          ).pipe(take(1))
        )
      ),
    );
  }

我想在最后加上一个take(devicesNumber),但是,如果我尝试在take(1) 之后将devicesNumber 设置为一个水龙头,它不起作用。

我该怎么做?

另外,我使用的那些take(1) 对自动退订真的有帮助吗?

【问题讨论】:

  • 很难知道您要达到的目标。 1 次发射后取消订阅。你包装了一个承诺,所以你真的不需要第二次 take() 因为承诺只发出和完成一次。
  • 很高兴了解take(1)。我想要实现的是在所有拉链都被触发后完成 observable。应用启动时只获取一次流
  • 如果我没记错的话,默认情况下会发生这种情况。当您订阅函数的结果时。它将触发调用,然后在所有内部可观察对象完成时完成。您的第一个 take(1) 也只会导致一次发射。流只被使用一次,因为它们源自只会完成一次的 Promise。

标签: angular rxjs


【解决方案1】:

您不能将数字或变量传递给take

此外,一旦您在take(1) 之后使用点击,点击将不会被激活。

另一件事是tap 是一个副作用,这意味着您不能将分配的值在点击内传播给操作员。

如果您需要有条件的take,那么您应该使用takeUntiltakeWhile

现在,专门针对您的问题,您以错误的方式使用take

这是zip 的定义:在所有可观察对象发出后,将值作为数组发出

这意味着如果所有 obervables 都已发出并且您拥有最终发出的数组,那么您应该对take(1) 很好,因为该过程是自动的。

不用担心take(devicesCounter)

另外,如果你不关心数组的最终结果,你可以使用forkJoin

forkJoin当所有可观察对象完成时,从每个对象发出最后一个发出的值

这意味着您已经知道所有的 observables 都已完成,因此您可以在 forkJoin 之后立即使用 take(1) 而无需担心。

综上所述,您当前的代码运行良好,您无需担心无关紧要的take(number)

【讨论】:

    猜你喜欢
    • 2019-09-21
    • 1970-01-01
    • 2018-10-17
    • 2018-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    相关资源
    最近更新 更多