如何将 Observable<string>[] 转换为 Observable<string[]>

How to convert Observable<string>[] to Observable<string[]>

我有一个包含对象数组的 Observable,我想使用第二个 observable 将它们转换为不同的对象。这是一个更大项目的一部分,所以为了简化我的问题,我将有一个具有数字数组的可观察对象,我想将它们转换为字符串。我从以下开始。

    const response$ = of({results: [1, 2, 3]});
    response$.pipe(
        map((response) => {
            return response.results.map((id) => {
                return id.toString();
            })
        })
    )
    .subscribe((response: string[]) => {
        console.log(response);
    })

订阅中的响应将是预期的字符串数组。现在我需要使用第二个 observable 将数字转换为字符串(再次只是为了让问题更简单)。所以我用 return of(id.toString()) 替换了 return id.toString() 来模拟对 observable 的第二次调用。

    const response$ = of({results: [1, 2, 3]});
    response$.pipe(
        map((response) => {
            return response.results.map((id) => {
                return of(id.toString());
            })
        }),
    )
    .subscribe((response: Observable<string>[]) => {
        
    })

现在响应的签名是 Observable<string>[] 但我需要响应是 string[] 所以我开始阅读其他 RxJS 运算符并最终得到以下结果。

    const response$ = of({results: [1, 2, 3]});
    response$.pipe(
        concatMap((response) => {
            return response.results.map((id) => {
                return of(id.toString());
            })
        }),
        concatAll()
    )
    .subscribe((response: string) => {
        console.log('bar', response);
    })

我使用了 concatMap()concatAll() 因为我需要按顺序调用第二个可观察对象。现在的问题是我的响应是一个字符串,我接到了三个订阅者 “1” “2” “3” 的电话。我需要一个 string[] 的回复。有人可以解释如何在我的示例中采用 Observable<string>[] 并将其转换为 Observable<string[]> 吗?

我想你要找的是这个:

const response$ = of({results: [1, 2, 3]});
response$.pipe(
    switchMap((response) => {
        // map array to observables and execute all with forkJoin
        return forkJoin(...response.results.map((id) => {
            return of(id.toString());
        }))
    })
)
.subscribe((response: string) => {
    console.log('bar', response);
})

但是,这将并行执行。如果你需要在内部顺序执行,你可以使用 concatreduce

const response$ = of({results: [1, 2, 3]});
response$.pipe(
    switchMap((response) => {
        // map array to observables and execute all with concat and collect results with reduce
        return concat(...response.results.map((id) => {
            return of(id.toString());
        })).pipe(reduce((acc, v) => acc.concat([v]), []))
    })
)
.subscribe((response: string) => {
    console.log('bar', response);
})

唯一要注意的是确保 response.results 中有物品。可能需要像这样的长度检查:

if (!response.results.length)
  return of([])