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

时间:2017-07-18 17:04:57

标签: angular http typescript observable

我有一个HTTP请求数组,我需要以某种顺序触发,但如果前一个请求失败,那么以下任何一个都不会被执行。

  1. 我如何实现这一目标?

  2. 最好的方法是什么?

  3. 我需要类似的东西:

      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')
           });
         }
      }
    

2 个答案:

答案 0 :(得分:3)

这需要一个Observable创建者合并发射的值,但只在每次完成后按顺序订阅。我不认为RxJs库中有类似的东西。

我确实写了一个工厂方法,我认为会产生你想要的东西:

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();
    });
}

请注意,我在HTTP observables中添加了take(1)运算符。这样做是为了让HTTP observable在产生响应后被销毁。因此,您不必打电话取消订阅。您可以使用take(1)first()执行相同操作,但在没有任何内容发布时它们的工作方式不同。

如果您发现运营商可以满足您的需求。请告诉我。

答案 1 :(得分:-1)

如果要发送多个HTTP请求,请使用ForkJoin。至于你的问题,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')

);