Angular 2 - Multiple HTTP request in the same time

橙三吉。 提交于 2019-12-11 03:41:42

问题


I'm actually working on an Angular 2 application but i have a some problems. Indeed, i have a method which get data from a database. However i'm trying to copy this data to an other one, to do that i need to do multiple HTTP request ( the requests number are never the same ).

Here is my migrate method. First I get the data from DB and then I try to post them in the other one

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

Or When i'm subribing to the method i have no Response from it.

Here is my subscriber

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

I want my method to return a Response when all the data has been post ! Actually when i'm calling the addData() method it doesn't even trigger the http request, nothing happens. I tryed to use some RxJs method like concat and forkJoin but nothing. Or just i failed using them.

Here is my addData() method

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

This method works very well for others use case.

Thanks for your help !


回答1:


Based on your code this is what I understood:

  1. Get some array from a service (from a rest call)
  2. Make a rest call for every element in that array
  3. Get a single result in the end when everything is done

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

This method works very well for others use case.

As a genereal note here: rxjs can be very poweful if used properly, almost everything can be written as a stream - as a rule of thumb you can remember to:

  • only use one subscribe per action (in your case the action is steps 1-3), if you are using more than one subscribe, you're not thinking in streams
  • try to avoid data-logic within the subscription, the subscription is best to be used for handling events/emits/results, e.g. migrationStream$.subscribe(..., ..., () => alert("Migration is complete!"));



回答2:


Here is my solution for multiple requests stream with 3 parallel requests

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


来源:https://stackoverflow.com/questions/40807725/angular-2-multiple-http-request-in-the-same-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!