我写了以下这段代码,试图解释我想要做什么。基本上,我有一个循环,如果在循环过程中满足特定条件,则会执行http POST。该POST将返回一个代码,该代码告诉我POST是成功还是失败。我想做的是,如果收到错误代码或引发异常,我将立即停止循环并显示错误消息。如果返回的代码成功,那么我将继续循环并可能执行另一个HTTP POST。我在这里苦苦挣扎的是整个异步的事情。我以编写该代码的方式,假设我不知道循环中HTTP POST的结果。我需要一种方法,当执行HTTP POST时,循环将不会继续,直到我获得该POST的结果为止。我在异步方面没有很多经验,这就是为什么我在这里寻求帮助。拜托,您能给我的任何见解将不胜感激。
sync() {
//some code here
for(var i = 0; i < length; i++){
if(condition){
//code
let r = this.syncPost(groupedData, options);
if(r != 'success') {
exit loop and show toast with error
}
}
}
}
syncPost(sd, options){
return new Promise((resolve) => {
let result = '';
this.http.post('path/to/url', sd, options)
.timeout(2 * 1000 * 60)
.map(res => res.json())
.subscribe(data => {
if(returnCode == successful){ //The API returns certain code that tell me that the post was successful
result = 'success'
}
else { //Post returned error code
result = 'not success [error code]'
}
//load.dismiss();
}, error => {
result = 'not success [error message]'
});
resolve(result);
});
}
答案 0 :(得分:0)
最好的答案是学习如何异步地执行您想要的事情,而不是与框架的设计争斗。
Angular的HttpClient返回Observables,并且像同步/异步问题一样,您可能应该学习顺应流程(双关语意),并使用RxJs而不是将Promises与Observables混合使用-从长远来看,这将变得更加容易。
要异步但顺序地执行Http请求,可以使用rxjs运算符“ concat”。
这是一个入门的简单示例。当收到HTTP错误时,此示例仅停止执行请求。根据您的错误处理/返回值检查,您可能需要更复杂的东西。
请注意,在此示例中,有四个潜在的请求,但是第三个请求失败,因为它将得到一个404(路径不存在):
还要注意,下面的'prepareOneRequest'方法实际上并不发出http请求。 它返回的Observable是一个“冷” Observable-在订阅之前,它不会发出请求,并且“ concat”方法将在上一个完成后一次预订一个Observable。 >
还要注意,在“真实”代码中,您不会在Angular组件中发出请求,而是将其放入服务中。
import { Component } from '@angular/core';
import { Observable, concat } from 'rxjs';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
urls = [
'https://jsonplaceholder.typicode.com/posts/1',
'https://jsonplaceholder.typicode.com/posts/2',
'https://jsonplaceholder.typicode.com/foo/3', /* this one doesn't exist */
'https://jsonplaceholder.typicode.com/posts/4'
];
constructor(private http: HttpClient) {
}
makeRequests() {
const observables: Observable<any>[] = [];
this.urls.forEach(url => observables.push(this.prepareOneRequest(url)));
concat(...observables).subscribe(
result => {
console.log('good result: ', result);
},
err => console.error('error: ', err)
);
}
prepareOneRequest(url: string): Observable<any> {
return this.http.get(url);
}
}