在 Angular 6 的 do while 循环中延迟递归 HTTP get 请求
Delaying recursive HTTP get request inside a do while loop in Angular 6
我在等待另一个 API 调用完成时递归地使用外部 API。
使用 import {HttpClient} from '@angular/common/http'
进行 http 调用
我是这个框架的新手,也许代码中有什么地方做错了,但工作流程如下:
第一个 API 调用是由这个块
initializeCrawling(): void {
this.callCrawlInitializingAPI() // this method is calling the api
.subscribe(
restItems => {
this.groupCrawlingRestResponse = restItems;
console.log(this.groupCrawlingRestResponse);
this.isCrawlActive = false;
}
)
this.fetchResults(); // while callCrawlInitializingAPi call executes, this block here must executed on paralel.
}
现在我要声明一个全局
boolean
当 this.callCrawlInitializingAPI()
执行完成时将变为 false
的变量。
这是必须递归调用的第二个 API 调用的代码。
fetchResults(): void {
this.fetchDataApiCall()
.subscribe(
restItems => {
this.groupCrawlingRestResponse = restItems;
console.log(this.groupCrawlingRestResponse);
}
)
}
fetchDataApiCall() {
do {
this.http
.get<any[]>(this.fetchResultsUrl, this.groupCrawlingResultRestResponse)
.pipe(map(data => data));
console.log("Delaying 3000");
} while (this.isCrawlActive);
}
这里的目标是将 do - while 循环延迟 1 秒。
我尝试了以下方法:
1 - 从 "rxjs/internal/operators" 导入 {delay} 并按上述方式使用;
do {
this.http
.get<any[]>(this.fetchResultsUrl, this.groupCrawlingResultRestResponse)
.pipe(map(data => data));
console.log("Delaying 3000");
delay(3000);
} while (this.isCrawlActive);
2- 使用上面的 setTimeout() 函数:
do {
setTimeout(function(){
this.http
.get<any[]>(this.fetchResultsUrl, this.groupCrawlingResultRestResponse)
.pipe(map(data => data));}, 1000)
} while (this.isCrawlActive)
None 他们正在工作,据我所知,do while 循环没有延迟,并且处理了很多调用,因为 do while continues。
首先我想知道如何让它工作,其次如果有更好的方法来使用 Angular 因为我是这个框架的新手。
谢谢
更新
如果以后有人搜索的话,我的问题有正确答案了
我唯一需要更改的是这行代码
clearInterval(intervalHolder.id)
首先,当您订阅包含 http 事件的函数时,该函数必须 return stream/http-call
fetchDataApiCall() {
return this.http
.get<any[]>(this.fetchResultsUrl, this.groupCrawlingResultRestResponse)
.pipe(map(data => data));
}
之后如果你想延迟响应,你必须把延迟运算符放在管道中,就像那样。
fetchDataApiCall() {
return this.http
.get<any[]>(this.fetchResultsUrl, this.groupCrawlingResultRestResponse)
.pipe(map(data => data),
delay(3000));
}
更新
由于更新前的评论说clear interval存在一些问题,所以这里是针对该案例的100%测试解决方案。第一个代码块中有轮询逻辑,几乎只要 isActive
属性 为真,每个 500 毫秒的新请求都会被调用。
第二个代码块是模拟请求的服务。
export class ChildOne {
longReqData;
shortReqData = [];
active = true;
constructor(private requester: RequesterService) {}
loadData() {
this.requester.startLongRequest().subscribe(res => {
this.longReqData = res;
console.log(res);
this.active = false;
});
let interval = Observable.interval(500);
let sub = interval.subscribe(() => {
this.requester.startShortRequest().subscribe(res => {
this.shortReqData.push(res);
console.log(res);
});
if (this.active === false) {
sub.unsubscribe();
}
});
}
}
@Injectable()
export class RequesterService {
private counter = 0;
stop() {
this.subject.next(false);
}
startShortRequest() {
this.counter += 1;
let data = {
delay: 0,
payload: {
json: this.counter
}
};
return this.mockRequest(data);
}
startLongRequest() {
let data = {
delay: 3000,
payload: {
json: "someJSON"
}
};
return this.mockRequest(data);
}
mockRequest(data) {
return Observable.of(data).pipe(delay(data.delay));
}
}
我在等待另一个 API 调用完成时递归地使用外部 API。
使用 import {HttpClient} from '@angular/common/http'
我是这个框架的新手,也许代码中有什么地方做错了,但工作流程如下:
第一个 API 调用是由这个块
initializeCrawling(): void {
this.callCrawlInitializingAPI() // this method is calling the api
.subscribe(
restItems => {
this.groupCrawlingRestResponse = restItems;
console.log(this.groupCrawlingRestResponse);
this.isCrawlActive = false;
}
)
this.fetchResults(); // while callCrawlInitializingAPi call executes, this block here must executed on paralel.
}
现在我要声明一个全局
boolean
当 this.callCrawlInitializingAPI()
执行完成时将变为 false
的变量。
这是必须递归调用的第二个 API 调用的代码。
fetchResults(): void {
this.fetchDataApiCall()
.subscribe(
restItems => {
this.groupCrawlingRestResponse = restItems;
console.log(this.groupCrawlingRestResponse);
}
)
}
fetchDataApiCall() {
do {
this.http
.get<any[]>(this.fetchResultsUrl, this.groupCrawlingResultRestResponse)
.pipe(map(data => data));
console.log("Delaying 3000");
} while (this.isCrawlActive);
}
这里的目标是将 do - while 循环延迟 1 秒。
我尝试了以下方法: 1 - 从 "rxjs/internal/operators" 导入 {delay} 并按上述方式使用;
do {
this.http
.get<any[]>(this.fetchResultsUrl, this.groupCrawlingResultRestResponse)
.pipe(map(data => data));
console.log("Delaying 3000");
delay(3000);
} while (this.isCrawlActive);
2- 使用上面的 setTimeout() 函数:
do {
setTimeout(function(){
this.http
.get<any[]>(this.fetchResultsUrl, this.groupCrawlingResultRestResponse)
.pipe(map(data => data));}, 1000)
} while (this.isCrawlActive)
None 他们正在工作,据我所知,do while 循环没有延迟,并且处理了很多调用,因为 do while continues。
首先我想知道如何让它工作,其次如果有更好的方法来使用 Angular 因为我是这个框架的新手。
谢谢
更新
如果以后有人搜索的话,我的问题有正确答案了
我唯一需要更改的是这行代码
clearInterval(intervalHolder.id)
首先,当您订阅包含 http 事件的函数时,该函数必须 return stream/http-call
fetchDataApiCall() {
return this.http
.get<any[]>(this.fetchResultsUrl, this.groupCrawlingResultRestResponse)
.pipe(map(data => data));
}
之后如果你想延迟响应,你必须把延迟运算符放在管道中,就像那样。
fetchDataApiCall() {
return this.http
.get<any[]>(this.fetchResultsUrl, this.groupCrawlingResultRestResponse)
.pipe(map(data => data),
delay(3000));
}
更新
由于更新前的评论说clear interval存在一些问题,所以这里是针对该案例的100%测试解决方案。第一个代码块中有轮询逻辑,几乎只要 isActive
属性 为真,每个 500 毫秒的新请求都会被调用。
第二个代码块是模拟请求的服务。
export class ChildOne {
longReqData;
shortReqData = [];
active = true;
constructor(private requester: RequesterService) {}
loadData() {
this.requester.startLongRequest().subscribe(res => {
this.longReqData = res;
console.log(res);
this.active = false;
});
let interval = Observable.interval(500);
let sub = interval.subscribe(() => {
this.requester.startShortRequest().subscribe(res => {
this.shortReqData.push(res);
console.log(res);
});
if (this.active === false) {
sub.unsubscribe();
}
});
}
}
@Injectable()
export class RequesterService {
private counter = 0;
stop() {
this.subject.next(false);
}
startShortRequest() {
this.counter += 1;
let data = {
delay: 0,
payload: {
json: this.counter
}
};
return this.mockRequest(data);
}
startLongRequest() {
let data = {
delay: 3000,
payload: {
json: "someJSON"
}
};
return this.mockRequest(data);
}
mockRequest(data) {
return Observable.of(data).pipe(delay(data.delay));
}
}