简体   繁体   English

Angular2 - 如何链接异步http请求并在失败时停止

[英]Angular2 - How to chain async http requests and stop if fails

I have an array of HTTP requests that I need to fire in certain order, but if any of the previous one fails then none of the following ones is going to be executed. 我有一个HTTP请求数组,我需要以某种顺序触发,但如果前一个请求失败,那么以下任何一个都不会被执行。

  1. How can I achieve that? 我怎样才能做到这一点?

  2. What's the best approach? 什么是最好的方法?

I need something like: 我需要这样的东西:

  let failed: boolean = false;
  payloadArray.forEach(payload => {
     if (!failed) {
     http.post(this.url, payload, this.options)
     .map((res: Response) => {
        return res.json;
      })
    .catch((error: any) => {
          failed = true;
          Observable.throw(error.json().error || 'Server error')
       });
     }
  }

This would require an Observable creator that merged the emitted values, but only subscribed in sequence after each completed. 这将需要一个Observable创建者合并发出的值,但只在每次完成后按顺序订阅。 I don't think there is anything like that in the RxJs library. 我不认为RxJs库中有类似的东西。

I did write a factory method that I think would yield what you want: 我写了一个工厂方法,我认为会产生你想要的东西:

public sequence(requests: Array<Observable<Response>>): Observable<Response[]> {
    return Observable.create((observer) => {
        const output = [];

        function executeHttp() {
            const request = requests.pop();
            if (request) {
                request.take(1).subscribe((value) => {
                    output.push(value);
                    executeHttp();
                }, (ex) => {
                    observer.error(ex);
                });
            } else {
                observer.next(output);
                observer.complete();
            }
        }

        executeHttp();
    });
}

Note that I added a take(1) operator to the HTTP observables. 请注意,我在HTTP observables中添加了一个take(1)运算符。 This was done to have the HTTP observables destroyed after they yield a response. 这样做是为了让HTTP observable在产生响应后被销毁。 So that you don't have to call unsubscribe. 这样您就不必打电话取消订阅。 You can use take(1) or first() which do the same thing, but they work differently when there is nothing emitted. 你可以使用take(1)first()做同样的事情,但是当没有任何东西发出时它们的工作方式不同。

If you find operators that do what you want. 如果你发现运营商做你想做的事。 Please let me know. 请告诉我。

if you want to send multiple HTTP requests, use ForkJoin . 如果要发送多个HTTP请求,请使用ForkJoin as for you question Http module handles both success and errors in the response 至于你的问题,Http模块处理响应中的成功和错误

let failed: boolean = false;
let sampleArr = [];

payloadArray.forEach(payload => {
    if (!failed) {
        sampleArr.push(this.http.post(this.url, payload, this.options))
    }
})

Observable.forkJoin(sampleArr).subscribe(
    (data) => this.data = data, 
    (err) => Observable.throw(err.json().error || 'Server error')

); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM