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 谈话完美地解释了它:
在您的示例中,您使用 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()
的可观察对象
我是 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 谈话完美地解释了它:
在您的示例中,您使用 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()
的可观察对象