与第一个请求一样,在2秒内执行第二个请求

时间:2020-07-28 08:34:42

标签: angular

我有两个要求。
我需要this.auth.login在执行this._auth.create之后的2秒钟内执行。

这不是我发生的事情。
我做错了什么?

auth() {
  this._auth.create(this.form.value).subscribe(
    () => {
      setTimeout(() => {
        this._auth.login(this.form.value).subscribe(
          () => {
            this.router.navigate(['/home']);
          },
          error => {
            this._toast.error(error.error.message);
          }
        );
      }, 2000)
      },
    error => {
      this._toast.error(error.error.message);
    }
  )
}

2 个答案:

答案 0 :(得分:2)

尽量避免嵌套订阅。相反,您可以使用RxJS operators来混合和匹配多个(相关的)可观察对象。

尝试以下

auth() {
  this._auth.create(this.form.value).pipe(
    delay(2000),
    switchMap(_ => this._auth.login(this.form.value))
  ).subscribe(
    _ => this.router.navigate(['/home']),
    error => this._toast.error(error.error.message)
  );
}

我已经使用delay运算符将第一个请求的通知延迟2秒钟,然后使用switchMap运算符将其切换到第二个请求。

但是在登录过程中引起固定的延迟并不是一个好的设计。如果您需要在此延迟期间实现一些副作用,那么另一种方法是将这些副作用包含在路由过程中,并使第二个呼叫直接等待第一个呼叫,而不是硬延迟。

答案 1 :(得分:0)

如果您使用RxJS提供的功能,我认为它会更具可读性:

concat(
  this._auth.create(this.form.value).pipe(
    tap({ error: () => this._toast.error(error.error.message) }),

    // make sure it goes to the next observable provided to `concat()`
    catchError(() => EMPTY)
  ),
  timer(2000).pipe(
    switchMap(
      () => this._auth.login(this.form.value).pipe(
        tap({
          next: () => this.router.navigate(['/home']);,
          error: () => this._toast.error(error.error.message);,
        }),
        catchError(() => EMPTY)
      )
    ),
  ),
);