Angular 2 - 多个HTTP请求在同一时间

问题描述:

我实际上在Angular 2应用程序上工作,但我有一些问题。事实上,我有一个从数据库中获取数据的方法。不过,我试图将这些数据复制到另一个,为此我需要做多个HTTP请求(请求数量从不相同)。Angular 2 - 多个HTTP请求在同一时间

这是我的迁移方法。首先我从数据库中的数据,然后我试图把它们发布到另一个

service.getDatas().subscribe(data => { 
    let datas = data.json().data; 
    if (datas) { 
    let requests = []; 
    for (let data of datas) { 
     let req = service.addData(data); // addData() return an Observable 
     requests.push(req); 
    } 
    let c: Observable<any> = Observable.forkJoin(requests); 
    return c; 
    } 
}); 

或者当我subribing到我有没有从它的响应方法。

这里是我的用户

service.migrateData(targetDB).subscribe(res => { 
     console.log(res); 
    }); 

我希望我的方法返回时,所有的数据已经发布回应! 实际上,当我调用addData()方法时,它甚至不会触发http请求,什么都不会发生。我尝试使用一些RxJs方法,如concat和forkJoin,但没有。或者只是我没有使用它们。

这里是我的addData()方法

addData(data) { 
    let headers = new Headers({ 
     'Content-Type': 'application/json' 
    }); 
    headers.append('Authorization', 'Basic ' + btoa('username + ':' + 'password)); 
    let _data = JSON.stringify({data: data}); 
    return this.http.post('https://something.com', _data, {headers: headers}); 
    } 

这种方法非常适用于其他的使用情况。

感谢您的帮助!

+0

我认为你需要在执行之前订阅可观察到的流。 service.addData(data)。subscribe() –

+0

如果我这样做,forkjoin将有一个订户数组,而不是一个可观察数组:/! –

+0

c.subscribe()? https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/forkjoin.md –

基于您的代码,这是我的理解:

  1. 获得从服务的一些阵列(从静止调用)
  2. 做一个REST调用该阵列中的每个元素
  3. 得到一个单个结果到底什么时候一切都做

const migrationStream$ = service.getDatas() 
    .map(data => data.json().data || [])  // and alternative to the "|| []" could be a subsequent ".filter(data => data && data.length)" 
    .switchMap(datas => Observable.from(datas)) // split up the js-array into a stream 
    .concatMap(data => service.addData(data)) 
    // .map(singleMigrateResponse => doSomethingWith(singleMigrateResponse)) // optional, is called for every data that is migrated 
    .toArray() // optional: this will wait for the previous part of the stream to complete and return an array of all results, remove this if you want to receive every result as a single "next" 

// run it by using: 
migrationStream$.subsribe(next..., error..., complete...); 

此方法对其他用例非常有效。

作为genereal笔记这里:如果使用得当rxjs可以很飞机的强大动力,几乎都可以写成流 - 作为一个经验法则,你可以记住:

  • 只使用一个订阅每行动(在你的情况下,行动是步骤1-3),如果你使用多个订阅,你不想在流
  • 尽量避免订阅中的数据逻辑,订阅最好用于处理事件/发射/结果,例如migrationStream$.subscribe(..., ...,() => alert("Migration is complete!"));

这里是我的解决方案多个请求有3名平行的请求

import {Component, OnInit} from '@angular/core'; 
import {HttpClient} from '@angular/common/http'; 

@Component({ 
    selector: 'app-multi-http', 
    template: `<ul> 
    <li *ngFor="let giphy of giphys"> <img src="{{giphy}}" width="200px"/> </li> 
    </ul>`, 
}) 
export class MultiHttpComponent implements OnInit { 
    // Requests stream vars 
    maxRequests = 3; 
    currentRequestsNbr = 0; 
    requestsStream = ['run', 'jump', 'hide', 'fight', 'surprise', 'sleep']; 

    giphys = []; 

    constructor(public http: HttpClient) { 
    } 

    ngOnInit() { 
     this.handleRequestsStream(); 
    } 


    handleRequestsStream() { 
     if (this.requestsStream.length > 0) { 
      if (this.currentRequestsNbr < this.maxRequests) { 
       ++this.currentRequestsNbr; 
       const searchTerm = this.requestsStream.shift(); 
       this.getGiphy(searchTerm).subscribe(
        url => { 
         this.giphys.push(url); 
        }, 
        error => { 
         console.log(error); 
        }, 
        () => { 
         --this.currentRequestsNbr; 
         // Try next request on complete 
         this.handleRequestsStream(); 
        } 
       ); 
       // Try next request 
       this.handleRequestsStream(); 
      } 
     } 
    } 

    getGiphy(searchTerm) { 
     const apiLink = '//api.giphy.com/v1/gifs/search?api_key=dc6zaTOxFJmzC&q=' + searchTerm; 
     return this.http.get(apiLink).map((response: any) => { 
      if (response.data.length > 0) { 
       return response.data[0].images.original.url; 
      } else { 
       return 'https://media.giphy.com/media/YaOxRsmrv9IeA/giphy.gif'; // dancing cat for 404 
      } 
     }); 
    } 
}