简体   繁体   English

RxJS (Interval) Observable 等待最后一个 observable 完成

[英]RxJS (Interval) Observable wait for last observable to complete

I want an interval observable which waits for the last execution.我想要一个可观察的间隔,它等待最后一次执行。 This are my tries.这是我的尝试。

Simple thing which not wait.简单的事情,不等待。

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

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

Next try but a bit bad.下一次尝试,但有点糟糕。

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 waits only before the first thing is true. skipWhile 仅第一件事为真之前等待。

Now I tried switchMap which also not works.现在我尝试了 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);
  });

Also not working:也不工作:

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);
  });

Is there a solution to realize that?有没有解决方案来实现这一点? Waiting for last observable to finish?等待最后一个 observable 完成? After the subscribe there is no chance to do that.订阅后没有机会这样做。 So how I can do this before.那么我以前怎么能做到这一点。

//edit 1: What I want? //编辑1:我想要什么?

I have an interval which executes an HTTP Request within.我有一个执行 HTTP 请求的间隔。 So when the HTTP Request waits for few seconds the next interval will be executed so that the request ist executed multiple times.因此,当 HTTP 请求等待几秒钟时,将执行下一个间隔,以便多次执行请求。

That I want to avoid.我想避免的。

MergeMap is not working, too. 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);
  });

I'm not sure what you're asking, but if user AJT82 is right (Ie, You'd like to drop any emissions from the interval while the previous request hasn't completed)我不确定你在问什么,但如果用户 AJT82 是正确的(即,你想在上一个请求尚未完成时从间隔中删除任何排放)

Here's how I would implement this:以下是我将如何实现它:

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")
});

An Aside on async/await关于 async/await 的旁白

Observables are a strict superset of promises. Observables 是 Promise 的严格超集。 This means that if you can do something with a promise, you can do it with an observable as well.这意味着如果你可以用 promise 做某事,你也可以用 observable 做这件事。

Unlike Promises though, Observables don't have special syntactic sugar like async/await.不过,与 Promises 不同的是,Observables 没有像 async/await 这样的特殊语法糖。

Observables interoperate with Promises fairly well. Observables 与 Promises 的互操作性相当好。 Most operators work with promises as well as with observables by converting promises for you in the background.大多数操作员通过在后台为您转换 Promise 来处理 Promise 和 observables。

This makes it helpful if your project is using one and you'd like to include a library that uses the other.如果您的项目正在使用一个并且您想包含一个使用另一个的库,这将很有帮助。

On the other hand , if your code is already using the machinery of observables, there is never ever a reason to use promises.另一方面,如果你的代码已经在使用 observables 机制,那么就永远没有理由使用 Promise。 This is a code-smell should be avoided unless you really have pretty good reasons.除非您真的有很好的理由,否则应该避免这种代码气味。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM