【问题标题】:RxJS (Interval) Observable wait for last observable to completeRxJS (Interval) Observable 等待最后一个 observable 完成
【发布时间】:2021-08-28 11:32:15
【问题描述】:

我想要一个等待最后一次执行的可观察间隔。 这是我的尝试。

不等待的简单事情。

interval(1000)
  .subscribe(async x => {
    await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 10000) + 1000));
    console.log('Got counter', x);
  });

结果:4, 1, 2, 6, 9, 7, 6, 3, ...

下一次尝试,但有点糟糕。

let alreadyRunning = false;
interval(1000)
  .pipe(skipWhile(() => alreadyRunning))
  .subscribe(async x => {
    alreadyRunning = true;
    await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 10000) + 1000));
    console.log('Got counter', x, alreadyRunning);
    alreadyRunning = false;
  });

skipWhile 只等待第一件事为真之前。

现在我尝试了同样不起作用的 switchMap。

interval(1000)
  .pipe(switchMap(() => from(new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 10000) + 1000)))))
  .subscribe(async x => {
    console.log('Got counter', x);
  });

也不行:

interval(1000)
  .pipe(switchMap(x => from(async () => {
    await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 10000) + 1000));
    console.log('Got counter', x);
    return x;
  })))
  .subscribe(async x => {
    console.log('X', x);
  });

是否有解决方案来实现这一点?等待最后一个 observable 完成? 订阅后没有机会这样做。 那么我以前怎么能做到这一点。

//编辑1: 我想要什么?

我有一个在其中执行 HTTP 请求的间隔。 因此,当 HTTP 请求等待几秒钟时,将执行下一个间隔,以便多次执行请求。

我想避免的。

MergeMap 也不起作用。

interval(1000)
  .pipe(mergeMap(x => from(new Promise(resolve => setTimeout(() => resolve(x), Math.floor(Math.random() * 10000) + 1000)))))
  .subscribe(async x => {
    console.log('Got counter', x);
  });

【问题讨论】:

  • 抱歉,Patrick,我看到你努力详细地写下你的问题,但不清楚你在问什么或你想要什么。例如,在您的任何示例中都没有最后的排放,那么您怎么能等待呢?
  • 我说得对吗,目标是发射从 0 到无穷大的不断增加的值,但在下一次发射前等待随机时间?
  • 我同意 Daniel Gimenez 的观点,我不太了解您正在寻找的行为。你能澄清一下吗?
  • interval$.pipe( skipUntil( observable$.pipe(last()) ) )
  • @DanielGimenez 我有一个 http 请求,希望等到最后一个请求完成。我更新了文字。希望它更清楚?像 Promise.resolve().then().then().then() 我需要 Observable.interval(1000).subscribe(async () => { WAIT FOR LAST ASYNC })。

标签: javascript angular typescript rxjs observable


【解决方案1】:

我不确定您在问什么,但如果用户 AJT82 是正确的(即,您想在上一个请求尚未完成的情况下从间隔中删除任何排放)

这是我将如何实现的:

interval(1000).pipe(
  tap(_ => console.log('interval hits every second!')),
  exhaustMap(_ => {
    console.log("request has started!")
    return timer(3000).pipe( // simulation that takes 3 seconds to complete
      tap(_ => console.log("request has finished!"))
    )
  })
).subscribe({
  next: v => console.log("Value emitted: ", v),
  error: e => console.log("Error emitted: ", e),
  complete: () => console.log("Complete emitted")
});

关于 async/await 的旁白

Observable 是 Promise 的严格超集。这意味着,如果你可以用 Promise 做某事,那么你也可以用 observable 做某事。

与 Promises 不同的是,Observables 没有像 async/await 这样的特殊语法糖。

Observables 与 Promises 的互操作性相当好。大多数操作员通过在后台为您转换 Promise 来处理 Promise 以及 Observables。

如果您的项目正在使用一个并且您希望包含一个使用另一个的库,这将很有帮助。

另一方面,如果你的代码已经在使用 observables 机制,那么永远不会有理由使用 Promise。除非您真的有充分的理由,否则应该避免这种代码异味。

【讨论】:

  • 不错的一个!我很确定 OP 的意思是“以前的”,而不是“最后的”:)
  • 这非常完美:-) 非常感谢!从未听说过exhaustMap。所以当请求完成时。当我取消订阅 observable 时,整个队列都被取消了,所以很好。
猜你喜欢
  • 2021-11-16
  • 2017-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多