代码之家  ›  专栏  ›  技术社区  ›  user3412296

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

  •  1
  • user3412296  · 技术社区  · 8 年前

    我在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
             });
         }
       }
    
    2 回复  |  直到 8 年前
        1
  •  0
  •   ShaneCoder    8 年前

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

    如果这不是一个选项,并且您希望一次提交一个请求,那么这里有一种不同的方法来处理控制器代码:

    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中输入了这个。你可能需要修正一些拼写错误。

        2
  •  0
  •   Pearman    8 年前

    你可以使用 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 对于每个已完成的事件,您将在订阅中获得一个事件。