我实际上正在开发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});
}
此方法适用于其他用例。
感谢您的帮助!
答案 0 :(得分:1)
根据您的代码,我理解这一点:
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如果使用得当可以非常强大,几乎所有东西都可以写成一个流 - 根据你的经验,你可以记住:
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
}
});
}
}