只要有可能,我就需要同时发出所有请求.以下是我的代码的简化版本:

const arr = [
  'https://jsonplaceholder.typicode.com/users/1',
  'https://jsonplaceholder.typicode.com/users/2',
  'https://jsonplaceholder.typicode.com/users/3',
];

let observables = [];
for (let url of arr) {
  observables.push(this.http.get(url));
}

const obs$ = this.http.get('http://localhost:3000/users').pipe(
  map((data: any) => {
    //an array of urls like https://jsonplaceholder.typicode.com/users/5
    let urls = data.data;
    let observables = [];
    for (let url of urls) {
      observables.push(this.http.get(url));
    }
    return observables;
  }),
  mergeMap((data) => forkJoin([...data]))
);

forkJoin([...observables, obs$]).subscribe({
  next: (data) => console.log(data, 'from fork'),
  error:(err)=>console.log(err)
});

所以,在这种情况下,我有:

  1. 一组可观测对象observables
  2. 一个可观察的obs$,它获取一些URL,在获取URL时,我还需要并行地向这些URL发出请求.

我不在乎结果,我只关心有没有什么差错.这些示例代码似乎工作正常,但是,我有几个问题,因为我试图理解RxJS.

  1. 为了达到我上面描述的目标,这是一种正确的做事方式吗?
  2. 这里的mergeMap((data) => forkJoin([...data]))->mergeMap基本上只是帮助我从嵌套的可观测对象中获得一个可观测对象,对吗?所以从技术上讲,我可以使用连接映射或切换映射来达到相同的效果?

推荐答案

您实际上不需要forkJoin,您只需创建一个发出单个URL的可观测对象,然后使用mergeMap来请求该URL并发出结果.

由于您有两个不同的url来源,我们可以分别定义这两个来源,然后使用merge从两个来源创建单个观察点:

const urls_1$: Observable<string> = from(arr);

const urls_2$: Observable<string> = this.http.get('http://localhost:3000/users').pipe(
  mergeMap(response => response.data)
);

const response$ = merge(urls_1$, urls_2$).pipe(
  mergeMap(url => this.http.get(url))
).

response$.subscribe({
  next: data => console.log(data),
  error: err => console.log(err)
});
  • urls_1$:我们使用from来创建逐个发出数组元素的可观测对象

  • urls_2$:我们进行http调用,然后使用mergeMap逐个发出接收到的数组元素.这与上面的from(in fact 101 used 102 internally)具有相同的效果.你是对的,你可以在这里使用任何更高阶运算符.

  • responses$:在这里,我们使用merge从两个来源创建单个可观测对象.这意味着只要url_1$url_2$发出一个值,"合并可观测对象"就会发出它.然后我们使用mergeMap来使http调用发出其结果.与前面的mergeMap不同,这个不能被switchMapconcatMap替代,因为您希望请求并行进行.这里的结果是我们的response$个可观察对象将发出每个请求的响应.

    • 如果您想限制并发请求的数量,可以将第二个concurrency参数提供为mergeMap:
mergeMap(url => this.http.get(url), 5) // <-- limit to 5 active requests

Angular相关问答推荐

如何在Angular应用程序部署中安全地管理环境变量

布局之间的Angular 变化检测需要重新加载

无法执行CanDeactivateFn Karma Test Angular 16

NG-BOOTSTRAPP SCROLLESPY没有高度就不能工作?

在Angular 17独立模式下,如何使用Swiper 11.0.5版使Bootstrap下拉菜单在Swiper元素外部可见

类是一个独立的组件,不能在Angular中的`@NgModule.bootstrap`数组中使用

Angular 16模块中未使用的组件是否从Bundle 包中删除(树摇动)?

如何修复不允许的HttpErrorResponse 405?

Angular 迁移 14 到 15 / 16:angular universal 是否停止将 <!-- this page was prerendered with angular universal --> 用于预渲染页面?

在生产模式下使用带Angular 的 livekit

BehaviorSubject 在 Angular 中制作数据之间的时间表(或计时器)

Chart.js 如何编辑标题标签 colored颜色

TypeError:this.restoreDialogRef.afterClosed 不是函数

单选按钮的Angular2 Reactive Forms formControl

Angular 2+ 一次性绑定

如何在插值中编写条件?

如何在 ngFor angular 2 内部使用 track

Angular 2 Material Design 组件是否支持布局指令?

Angular将 Select 值转换为 int

Angular2中是否有像window.onbeforeunload这样的生命周期钩子?