Angular 2 - 同时发出多个HTTP请求

时间:2016-11-25 14:59:52

标签: javascript angular typescript rxjs

我实际上正在开发Angular 2应用程序,但我遇到了一些问题。实际上,我有一种从数据库中获取数据的方法。但是我试图将这些数据复制到另一个数据,为此我需要做多个HTTP请求(请求数量永远不会相同)。

这是我的迁移方法。首先,我从DB获取数据,然后尝试将它们发布到另一个

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

或者当我实施该方法时,我没有响应。

这是我的订阅者

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

此方法适用于其他用例。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

根据您的代码,我理解这一点:

  1. 从服务中获取一些数组(来自其他通话)
  2. 对该数组中的每个元素进行休息调用
  3. 当一切都完成后,最终得到一个结果
  4. 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...);
    
      

    此方法适用于其他用例。

    作为一个真实的注释:rxjs如果使用得当可以非常强大,几乎所有东西都可以写成一个流 - 根据你的经验,你可以记住:

    • 每个操作只使用一个订阅(在您的情况下,操作是步骤1-3),如果您使用多个订阅,则您需要不想在溪流中
    • 尝试避免订阅中的数据逻辑,订阅最好用于处理事件/发出/结果,例如, migrationStream$.subscribe(..., ..., () => alert("Migration is complete!"));

答案 1 :(得分:0)

这是我针对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
            }
        });
    }
}