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});
}
这种方法非常适用于其他的使用情况。
感谢您的帮助!
答
基于您的代码,这是我的理解:
- 获得从服务的一些阵列(从静止调用)
- 做一个REST调用该阵列中的每个元素
- 得到一个单个结果到底什么时候一切都做
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
}
});
}
}
我认为你需要在执行之前订阅可观察到的流。 service.addData(data)。subscribe() –
如果我这样做,forkjoin将有一个订户数组,而不是一个可观察数组:/! –
c.subscribe()? https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/forkjoin.md –