哪个更合适——concat 还是 map?
What's more appropriate - concat or map?
我想执行 2 个 promise,然后将 promise2 的结果传递给一堆其他 rxjs 运算符,以便在 promise2 解析时做一堆不同的事情。但我希望 promise2 仅在 promise1 解析时执行。为了获得这种效果,我应该使用类似
的东西吗?
from(promise1).pipe(
map(x => promise2),
tap((x) => console.log('response from map: ', x)),
other_rxjs_ops)
.subscribe(...)
如果我使用 concat 而不是 map
concat(promise1, defer(() => promise2)).pipe(
tap(console.log('response from map: ', x)),
other_rxjs_ops))
.subscribe(...)
我假设会发生的事情是 promise1 将执行,如果它解析,promise2 将执行,然后两个 promise 的结果将通过其他 rxjs 运算符并被订阅,对吗?
那么我使用 map 获得所需结果的方法是否合适,或者我应该考虑使用另一个 rxjs 运算符来执行 promise1 和 promise2?我 运行 在使用 map
时遇到的一个问题是 tap
中的 console.log 似乎在 map
中的承诺已解决或出错之前执行,并且控制台打印以下内容:
response from map: undefined //presuming promise2 hasn't had a chance to resolve yet, which is why we're getting undefined because the promise is designed to return a string value.
使用 concatMap 而不是 map 解决了这个问题,但我不明白为什么 tap 的行为方式与 map 一起使用时的行为方式。对此的任何指导也会有所帮助。
在您的情况下,您可以使用 Higher-Order RxJS mapping operators 之一,例如 concatMap
、mergeMap
或 switchMap
,将流相互合并。
您可以尝试以下操作:
from(promise1)
.pipe(
// promise2 won't be executed until the promise1 is resolved.
concatMap((val1) => from(promise2)),
// tap won't be executed until the promise2 is resolved.
tap((val2) => console.log('response from promise2:', val2))
// Other RxJS operators here...
)
.subscribe();
备注:
-
map
运算符用于将值转换为另一种类型,在您的情况下,它用于将 promise1
结果转换为 Promise
,但是,它不会'订阅它也没有将它转换为Observable
,所以tap
转换后直接执行,而不是等待它被解析。
- (可选)要订阅
promise1
,应使用 from
函数将其转换为 Observable
。
- 要订阅新的
Observable
,它应该与原来的 from(promise1)
合并,使用 higher-order 映射运算符之一,而不是使用正常的 map
。
关于你的第一个选择
您正在使用 map
运算符,发现 tap
没有等待 promise 被解析。
所以这里发生了什么,map
运算符不订阅内部可观察对象,因此它返回 promise 对象 (Promise {}
) 并且不会等待待解决,因为 tap
操作员在这里记录这个 - response from map: Promise {}
任何高阶映射(concatMap
mergemap
switchMap
ExhaustMap
) 订阅内部observable.Know more: link1 | Link2
因此在这段 concatMap(x => promise2)
代码中,concatMap
将订阅 promise2
并在 promise2
得到解析时发出数据。
第一个选项使用 concatMap
from(promise1)
.pipe(
concatMap((x) => promise2),
tap((x) => console.log('response from map: ', x))
// other_rxjs_ops...
)
.subscribe();
在你的情况下 source observable 即 from(promise1
) 一旦 promise1
是 resolved.After 从 promise1 收到响应,concatMap
将订阅 promise2
一个 Promise 只能发出一个数据,要么 resolve 要么 reject,所以你也可以在这里使用 mergeMap
或任何更高阶的 map 运算符。
所以你可以考虑第一个选项如果你需要使用promise1
响应调用promise2
。
现在进入您的第二个选项,它使用concat。
因此,如果 promise2
不依赖于 promise1
的响应,您可以考虑第一个选项。
简单地说,您的要求是在 promise1
完成后调用 promise2
我提供了一个工作示例,您可以通过它来解决您的疑虑
import { concat, from, interval, of } from 'rxjs';
import {
concatMap,
exhaustMap,
map,
mergeMap,
switchMap,
take,
tap,
} from 'rxjs/operators';
const source = interval(1000).pipe(take(5));
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise1 resolved!');
// reject('Promise1 rejected!');
}, 5000);
});
/*..............Option 1..............*/
source
.pipe(
mergeMap((result) => {
console.log("Inside pipe: ",result);
return promise1;
})
// concatMap(()=>promise1),
)
.subscribe({
next: console.log,
error: console.error,
complete: () => console.log('Completed!'),
});
// source.pipe(
// tap(console.log),
// map(()=>promise1),
// ).subscribe(console.log);
/*..............Option 2..............*/
concat(source, promise1).subscribe({
next: console.log,
error: console.error,
complete: () => console.log('Completed!'),
});
我想执行 2 个 promise,然后将 promise2 的结果传递给一堆其他 rxjs 运算符,以便在 promise2 解析时做一堆不同的事情。但我希望 promise2 仅在 promise1 解析时执行。为了获得这种效果,我应该使用类似
的东西吗?from(promise1).pipe(
map(x => promise2),
tap((x) => console.log('response from map: ', x)),
other_rxjs_ops)
.subscribe(...)
如果我使用 concat 而不是 map
concat(promise1, defer(() => promise2)).pipe(
tap(console.log('response from map: ', x)),
other_rxjs_ops))
.subscribe(...)
我假设会发生的事情是 promise1 将执行,如果它解析,promise2 将执行,然后两个 promise 的结果将通过其他 rxjs 运算符并被订阅,对吗?
那么我使用 map 获得所需结果的方法是否合适,或者我应该考虑使用另一个 rxjs 运算符来执行 promise1 和 promise2?我 运行 在使用 map
时遇到的一个问题是 tap
中的 console.log 似乎在 map
中的承诺已解决或出错之前执行,并且控制台打印以下内容:
response from map: undefined //presuming promise2 hasn't had a chance to resolve yet, which is why we're getting undefined because the promise is designed to return a string value.
使用 concatMap 而不是 map 解决了这个问题,但我不明白为什么 tap 的行为方式与 map 一起使用时的行为方式。对此的任何指导也会有所帮助。
在您的情况下,您可以使用 Higher-Order RxJS mapping operators 之一,例如 concatMap
、mergeMap
或 switchMap
,将流相互合并。
您可以尝试以下操作:
from(promise1)
.pipe(
// promise2 won't be executed until the promise1 is resolved.
concatMap((val1) => from(promise2)),
// tap won't be executed until the promise2 is resolved.
tap((val2) => console.log('response from promise2:', val2))
// Other RxJS operators here...
)
.subscribe();
备注:
-
map
运算符用于将值转换为另一种类型,在您的情况下,它用于将promise1
结果转换为Promise
,但是,它不会'订阅它也没有将它转换为Observable
,所以tap
转换后直接执行,而不是等待它被解析。 - (可选)要订阅
promise1
,应使用from
函数将其转换为Observable
。 - 要订阅新的
Observable
,它应该与原来的from(promise1)
合并,使用 higher-order 映射运算符之一,而不是使用正常的map
。
关于你的第一个选择
您正在使用 map
运算符,发现 tap
没有等待 promise 被解析。
所以这里发生了什么,map
运算符不订阅内部可观察对象,因此它返回 promise 对象 (Promise {}
) 并且不会等待待解决,因为 tap
操作员在这里记录这个 - response from map: Promise {}
任何高阶映射(concatMap
mergemap
switchMap
ExhaustMap
) 订阅内部observable.Know more: link1 | Link2
因此在这段 concatMap(x => promise2)
代码中,concatMap
将订阅 promise2
并在 promise2
得到解析时发出数据。
第一个选项使用 concatMap
from(promise1)
.pipe(
concatMap((x) => promise2),
tap((x) => console.log('response from map: ', x))
// other_rxjs_ops...
)
.subscribe();
在你的情况下 source observable 即 from(promise1
) 一旦 promise1
是 resolved.After 从 promise1 收到响应,concatMap
将订阅 promise2
一个 Promise 只能发出一个数据,要么 resolve 要么 reject,所以你也可以在这里使用 mergeMap
或任何更高阶的 map 运算符。
所以你可以考虑第一个选项如果你需要使用promise1
响应调用promise2
。
现在进入您的第二个选项,它使用concat。
因此,如果 promise2
不依赖于 promise1
的响应,您可以考虑第一个选项。
简单地说,您的要求是在 promise1
promise2
我提供了一个工作示例,您可以通过它来解决您的疑虑
import { concat, from, interval, of } from 'rxjs';
import {
concatMap,
exhaustMap,
map,
mergeMap,
switchMap,
take,
tap,
} from 'rxjs/operators';
const source = interval(1000).pipe(take(5));
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise1 resolved!');
// reject('Promise1 rejected!');
}, 5000);
});
/*..............Option 1..............*/
source
.pipe(
mergeMap((result) => {
console.log("Inside pipe: ",result);
return promise1;
})
// concatMap(()=>promise1),
)
.subscribe({
next: console.log,
error: console.error,
complete: () => console.log('Completed!'),
});
// source.pipe(
// tap(console.log),
// map(()=>promise1),
// ).subscribe(console.log);
/*..............Option 2..............*/
concat(source, promise1).subscribe({
next: console.log,
error: console.error,
complete: () => console.log('Completed!'),
});