在RxJS中,映射不执行内部映射的可观察对象
RxJS是新手,但我尝试将一个元素流映射到另一个元素流,在所有内部/后续流完成/加载后生成一个数组。然而,我的内在观察似乎没有执行。他们只是感冒了才回来 在高层,我需要执行HTTPPOST来上传文件列表(在两个不同的数组中,上传到两个不同的端点)。由于它们很大,我以5秒的延迟进行仿真。请求需要并行执行,但限于一次并发执行X(这里是2)。这一切都需要在管道内,管道应该只允许流在所有帖子完成后继续 内部订阅不会等到它们完成。使用forkJoin不允许我限制并发上传。我怎样才能做到这一点 更新: @dmcgrandle的回答非常有帮助,让我做出了以下似乎有效的更改:在RxJS中,映射不执行内部映射的可观察对象,rxjs,rxjs6,Rxjs,Rxjs6,RxJS是新手,但我尝试将一个元素流映射到另一个元素流,在所有内部/后续流完成/加载后生成一个数组。然而,我的内在观察似乎没有执行。他们只是感冒了才回来 在高层,我需要执行HTTPPOST来上传文件列表(在两个不同的数组中,上传到两个不同的端点)。由于它们很大,我以5秒的延迟进行仿真。请求需要并行执行,但限于一次并发执行X(这里是2)。这一切都需要在管道内,管道应该只允许流在所有帖子完成后继续 内部订阅不会等到它们完成。使用forkJoin不允许我限制并发上传。我怎样才能做到这一点 更新: @
import { map, mapTo, mergeMap, mergeAll, delay, tap, catchError, toArray } from 'rxjs/operators';
import { interval, merge, forkJoin, of, from, range, Observable, throwError } from 'rxjs';
const single = "name";
const first = ["abc", "def"];
const second = of("ghi", "jkl", "mno");
of(single)
.pipe(tap(val => console.log(`emit:${val}`)))
.pipe(
mergeMap(claim =>
merge(
from(first).pipe(map(photo => of(photo).pipe(delay(5000)).pipe(tap(val => console.log(`emit:${val}`))))),
from(second).pipe(map(video => of(video).pipe(delay(5000)).pipe(tap(val => console.log(`emit:${val}`)))))
)
),
mergeAll(2),
toArray()
)
.pipe(
catchError(error => {
console.log("error");
return throwError(error);
})
)
.subscribe(val => console.log(`final:${val}`));
如果我理解正确,那么我认为这是一个解决方案。您的问题是第一个
映射
,它不会执行内部订阅,而只是将流转换为可观察对象的可观察对象,这似乎不是您想要的。相反,我在那里使用了mergeMap
在from
的内,我使用concatMap强制第一次和第二次的发射按顺序进行,并等待一次发射完成,然后再开始另一次发射。我还设置了postToEndpoint
函数,这些函数返回的观察值更接近实际代码的样子
演示
代码:
我希望这有帮助。非常有帮助。postToEndpoints使事情更加清楚。我希望在并发限制/限制之前合并阵列,以便(a)它可以处理一个比另一个大得多的阵列,以及(b)我可以将并发限制增加到5左右。你的回答让我找到了实现这一点所需的更改(请参阅原始帖子中的更新)。如果它让你找到了正确的解决方案,当然。请注意,指南中说“接受答案并不意味着是表明问题现在已得到完美回答的决定性和最终声明”。但正如指南中所说,如果你不想接受答案,你不应该感到被迫接受不管怎样,我很高兴你把它整理好了。快乐编码。
import { map, mapTo, mergeMap, mergeAll, delay, tap, catchError, toArray } from 'rxjs/operators';
import { interval, merge, forkJoin, of, from, range, Observable, throwError } from 'rxjs';
const single = "name";
const first = ["abc", "def"];
const second = of("ghi", "jkl", "mno");
of(single)
.pipe(tap(val => console.log(`emit:${val}`)))
.pipe(
mergeMap(claim =>
merge(
from(first).pipe(map(photo => of(photo).pipe(delay(5000)).pipe(tap(val => console.log(`emit:${val}`))))),
from(second).pipe(map(video => of(video).pipe(delay(5000)).pipe(tap(val => console.log(`emit:${val}`)))))
)
),
mergeAll(2),
toArray()
)
.pipe(
catchError(error => {
console.log("error");
return throwError(error);
})
)
.subscribe(val => console.log(`final:${val}`));
import { mergeMap, concatMap, delay, tap, catchError, toArray } from 'rxjs/operators';
import { merge, of, from, concat, throwError } from 'rxjs';
const single = "name";
const first = ["abc", "def"];
const second = of("ghi", "jkl", "mno");
const postToEndpoint1$ = photo => of(photo).pipe(
tap(data => console.log('start of postTo1 for photo:', photo)),
delay(5000),
tap(data => console.log('end of postTo1 for photo:', photo))
);
const postToEndpoint2$ = video => of(video).pipe(
tap(data => console.log('start of postTo2 for video:', video)),
delay(5000),
tap(data => console.log('end of postTo2 for video:', video))
);
of(single).pipe(
tap(val => console.log(`initial emit:${val}`)),
mergeMap(claim =>
merge(
from(first).pipe(concatMap(postToEndpoint1$)),
from(second).pipe(concatMap(postToEndpoint2$))
)
),
toArray(),
catchError(error => {
console.log("error");
return throwError(error);
})
).subscribe(val => console.log(`final:`, val));