我正在尝试将现有的AngularJs代码迁移到Angular5。我目前在forEach函数中运行许多API调用。以前,我曾经为每个功能分别在$ q.defer中运行,在成功或错误函数调用中均运行.resolve()。之后,$ q.all。现在,我不确定如何将它与可观察对象一起使用。
这是我的组件的外观。
testArray = [1,2,3,4,5,.6];
resultArray = [];
constructor(private timeoutService: TimeoutService) {
this.testFn();
}
testFn(){
this.testArray.forEach((n) => {
this.timeoutService.getItemsCallback(n, this.successFn.bind(this), this.errorFn.bind(this))
})
}
successFn(r){
this.resultArray.push(r);
console.log(r)
}
errorFn(e){
this.resultArray.push(e);
console.log(e);
}
这是我的服务文件。
public GetItems(request: any): Observable<any> {
console.log(request)
return this.http.get(`https://jsonplaceholder.typicode.com/posts/${request}`);
}
getItemsCallback(request, successFn, errorFn) {
this.GetItems(request).
subscribe(
response => {
successFn(response);
},
error => {
errorFn();
}
);
}
所有API调用完成后,我想做些事情。我看到有一个名为forkJoin的函数,但是我不确定如何使用它。 这是一个实现这一目的的链接。 https://stackblitz.com/edit/angular-suetah?file=src%2Fapp%2Ftimeout.service.ts
答案 0 :(得分:0)
如果要执行几个带有存储在数组中的参数的http调用,然后在所有这些调用返回后都必须执行一些特定的操作,则可以考虑采用以下方法。
首先,使用RxJs 6.x的from
函数从参数数组中创建一个Observable。
然后,您使用mergeMap
(又称flatMap
)来将参数数组转换为表示http调用的Observables数组。
最后,您订阅激活Observable链并执行调用,并指定要在Observable链完成时(即当所有http调用都返回时)运行的功能。
代码如下所示
const testArray = [1,2,3,4,5,6];
from(testArray)
.pipe(
mergeMap(param => this.GetItems(param))
)
.subscribe(
result => {// do something with the result},
error => {// do something if an error occurs},
() => {// this is the function run when all of the httpCalls have returned}
)
答案 1 :(得分:0)
这有使用RxJS的多种解决方案。
此答案是Picci答案的补充。
Picci使用MergeMap。 MergeMap的问题在于,您获得的响应顺序有时可能与请求顺序不同。
ForkJoin,将保留订单并在收到所有响应后返回。
ConcatMap将保留订单,但在完成每个请求后将返回。
如果您不担心在完成所有请求之前等待的时间,我想您可以使用ForkJoin。
会是这样的:
testArray = [1,2,3,4,5,6];
obsArray = []
this.testArray.forEach((n) => {
this.obsArray.push(this.timeoutService.getItemsCallback(n))
})
forkJoin(this.obsArray).subscribe((res) => {
//Write code for success callback
},
(err) => {
//Write code for error callback
},
() => {
//Write code to do something when all requests are complete
})
但是,如果您想使用mergeMap或concatMap(请阅读上面的说明并做出决定),则可以执行Picci所做的事情。
如果您决定使用concatMap,只需在他的代码中将mergeMap更改为concatMap。