rxjs中switchmap的理解

understanding of switchmap in rxjs

我是 rxjs 的新手。我试图了解 switchmap 功能。为了理解,我写了下面的代码。

const fun1 = () => {
    return new Promise((resolve, reject) => resolve("Fun1"));
  };
  const fun2 = () => {
    return new Promise((resolve, reject) => resolve("Fun2"));
  };
  const fun3 = () => {
    return new Promise((resolve, reject) => resolve("Fun3"));
  };

  const observer = from(fun()).pipe(
    switchMap((result1) => {
      return from(fun1());
    }),
    switchMap((result2) => { 
      return from(fun2())
    }),
    switchMap((result3) => {
      return from(fun3());
    })
  );
  observer.subscribe(
    (val) => console.log("Val =", val),
    (error) => console.log("Error = ", error),
    () => console.log("Completed")
  );

以上代码 returns Fun3 给订阅者。

但我的期望是,如果 fun2() return 承诺使用“Fun2”字符串,那么代码不应使用 from(fun3()); 执行 switchmap;并且代码应该 return “Fun2 给订阅者。我怎样才能在上面提到的代码中实现这个功能。

switchMap 与 exhaustMap 或 mergeMap 一样,用于扁平化 observable 的 observable。 switchMap 的特殊之处在于,如果您的源可观察对象(在您的例子中:from(fun()))发出一个新值,则 switchMap 运算符将在订阅新值之前取消订阅先前的内部可观察对象。 因此,您将始终只有一个内部订阅。 这个 ng-conf 谈话完美地解释了它:

https://www.youtube.com/watch?v=rUZ9CjcaCEw

在您的示例中,您使用 pipe 函数对三个 switchMap 进行管道传输。您的可观察值(在您的订阅方法中)将始终是您在管道函数中所做的最后一次转换(在您的情况下为(“Fun3”))。

对于您的具体示例,您可以执行以下操作:

const observer = from(fun).pipe(
    switchMap((result2) => { 
      return from(fun2()).pipe(
        catchError(error => fun3())
      )
    })
  );

只有在 fun2() 拒绝时才会调用 fun3(),否则您的订阅者将收到 fun2() 的结果。

但我强烈建议您观看只有 20 分钟的演讲,它真正解释了 switchMap 的作用。

我已经重写了您的代码,因此可能更容易理解为什么您总是得到“fun3”。

const fun1 = () => of("Fun1");
const fun2 = () => of("Fun2");
const fun3 = () => of("Fun3");

const observable = from(fun()).pipe(
  switchMap(_ => fun1()),
  switchMap(_ => fun2()),
  switchMap(_ => fun3()),
);

observer.subscribe({
  next: val => console.log("Val =", val),
  error: err => console.log("Error = ", err),
  complete: () => console.log("Completed")
});

首先,请注意我的 switchMap 如何忽略它们的输入?这应该给你一个提示,即忽略先前可观察到的“return 值”。

switchMap(_ => fun1()) 是说“每当源可观察对象发出一个值(我不关心这个值是什么)时,然后订阅由 fun1 编辑的可观察对象 return。 “

这是另一个例子:

const observable = from(fun()).pipe(
  switchMap(result => result == "Fun2"? of(result) : fun1()),
  switchMap(result => result == "Fun2"? of(result) : fun2()),
  switchMap(result => result == "Fun2"? of(result) : fun3()),
);

现在您有了正在检查中间结果的可观察对象。

  • 第一个结果是 fun() 发出的结果,如果不是 "Fun2",则调用 fun1()
  • 第二个结果是 "Fun1",因为它也不是 "Fun2",所以 fun2() 被称为
  • 第三个结果是"Fun2"!啊哈!现在我们 return 发出 "Fun2" 而不是调用 fun3()
  • 的可观察对象