Angular 4 - 如何进行批量http同步请求

Angular 4 - How to make bulk http syncronous requests

我的 Angular 4 应用程序中有一个用于上传数据的处方集。此数据来自 JSON 个元素的数组,我循环遍历它以通过可观察对象发出 HTTP PUT 请求。

如果要上传一小部分元素,一切正常,但有时输入可能超过 1000 个元素。

因为我使用的是可观察对象,所以所有请求都是以同步方式发出的,所以是在同一时间。如果元素数量足够大,这会使后端崩溃。

我需要一个接一个地发出 HTTP 请求,但我不知道该怎么做。 ¿你能帮我吗?

服务功能:

putIp(ip, data): any {
const url = `${this.IpUrl}/${ip}`;
return this.authHttp.put(url, data, {headers: this.headers});}

组件函数:

       publishIps(): void {
     console.log("Publishing Ips")

     for (let _i = 0; _i < this.ipsInTable.length; _i++) {
         this.ipsInTable[_i].treated = true;
         this.ipService.putIp(this.ipsInTable[_i].id, this.ipsInTable[_i].json)
         .catch(err => {
           this.ipsInTable[_i].result = false;
           this.ipsInTable[_i].message = "Error";
           return Observable.throw(this.errorHandler(err));
         })
         .subscribe((data) => {
            // Doing some stuff
         });
     }
   }

我会调整后端以接受一组对象。然后你只做一个请求。

如果这不是一个选项,并且您希望一次提交一个请求,那么您可以使用控制器代码的另一种方法:

publishIp(_i: int): void {
   if (_i < this.ipsInTable.length) {

     this.ipsInTable[_i].treated = true;
     this.ipService.putIp(this.ipsInTable[_i].id, this.ipsInTable[_i].json)
     .catch(err => {
       this.ipsInTable[_i].result = false;
       this.ipsInTable[_i].message = "Error";
       return Observable.throw(this.errorHandler(err));
     })
     .subscribe((data) => {
       _i++;
       publishIp(_i);           
        // Doing some stuff
     });
  }
}
publishIps(): void {
 console.log("Publishing Ips");

 publishIp(0);     
}

免责声明: 我只是将其输入到 Whosebug 中。您可能需要更正一些拼写错误。

您可以使用带油门的 mergeMap。代码看起来像这样:

Observable
  // From takes an array and breaks each item into an individual event
  .from(arrayOfItems)
  // A mergeMap takes an event and converts it into a new observable
  // in this case -- a request. The second argument is how many items to 
  // allow in flight at once -- you can limit your network activity here.
  .mergeMap(item => saveItemObservable(item), requestLimit)
  // Will emit an event once all of the above requests have completed
  .toArray()
  // You will have an array of response results.
  .subscribe(arrayOfResults => { ... });

如果您使用的是较新版本的 RxJS,它将如下所示:

// You will need the correct imports:
// i.e import { from } from 'rxjs/observable/from';
// i.e. import { mergeMap, toArray } from 'rxjs/operators';
// From takes an array and breaks each item into an individual event
from(arrayOfItems).pipe(
     // A mergeMap takes an event and converts it into a new observable
     // in this case -- a request. The second argument is how many items to 
     // allow in flight at once -- you can limit your network activity here.
     mergeMap(item => saveItemObservable(item), requestLimit),
     // Will emit an event once all of the above requests have completed
     toArray()
  )
  // You will have an array of response results.
  .subscribe(arrayOfResults => { ... });

如果您删除 toArray 您将在订阅中为每个已完成的事件获得一个事件。