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

时间:2018-04-20 18:17:46

标签: angular observable synchronous bulk

我的Angular 4应用程序中有一个上传数据的处方集。这些数据来自一个JSON元素数组,我循环它以通过一个observable发出HTTP PUT请求。

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

当我使用observable时,所有请求都是以同步方式进行的,所以同时也是如此。如果元素的数量足够大,那么后端就会崩溃。

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

服务功能:

       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
         });
     }
   }

组件功能:

>>> line.domain.attributes[0].name
"Feature1"
>>> line.domain.metas[0].name
"Metadata1"

2 个答案:

答案 0 :(得分:1)

你可以使用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,则每个已完成的活动都会在订阅中收到一个事件。

答案 1 :(得分:0)

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

如果这不是一个选项,并且您希望一次提交一个请求,则这是一种与控制器代码不同的方法:

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);     
}

免责声明:我只是将其输入stackoverflow。你可能要修正一些拼写错误。