在收到我的HTTP Post响应之前,如何停止循环继续? (离子3)

时间:2018-07-14 16:50:00

标签: angular ionic3

我写了以下这段代码,试图解释我想要做什么。基本上,我有一个循环,如果在循环过程中满足特定条件,则会执行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);
    });
  }

1 个答案:

答案 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);
  }
}