简体   繁体   English

Angular 2为什么我的4个api调用在执行之前不等待上一个调用完成?

[英]Angular 2 why aren't my 4 api calls waiting for the previous call to finish before executing?

I have a form / component that has to do 4 separate API calls in order to do a "save". 我有一个form / component ,必须执行4个单独的API调用才能进行“保存”。 Really, only one of those transactions needs to wait for the other 3, but I wanted to chain all 4 of them anyway just to be safe. 确实,这些事务中只有一个需要等待其他三个事务,但是为了安全起见,我还是想将所有这四个事务链接在一起。

Here's how I have it setup: 这是我的设置方法:

save() {
    this.save1(saveObject1)
        .subscribe(response => {
            if (response === 0) {
                this.processErrorResult('save1');
            }

            this.save2(saveObject2)
                .subscribe(response2 => {
                    if (response2 === 0) {
                        this.processErrorResult('save1');
                    }

                    this.save3(saveObject3)
                        .subscribe(response3 => {
                            if (response3 === 0) {
                                this.processErrorResult('save1');
                            }

                            if (this.noErrorsInFirst3Saves()) {
                                this.save4(saveObject4)
                                    .subscribe(response4 => {
                                        if (response4 === 0) {
                                            this.processErrorResult('save1');
                                        }

                                        if (!this.hasErrors()) {
                                            this.router.navigate(['confirmation']);
                                        }
                                    });
                            }
                        });
                });
        });
}

private save1(saveObject: any): Observable<int> {
    this.api.save1(saveObject)
        .subscribe(successful => {
            return Observable.of(1);
        }, failed => {
            return Observable.of(0);
        });
}

private save2(saveObject: any): Observable<int> {
    this.api.save2(saveObject)
        .subscribe(successful => {
            return Observable.of(1);
        }, failed => {
            return Observable.of(0);
        });
}

private save3(saveObject: any): Observable<int> {
    this.api.save3(saveObject)
        .subscribe(successful => {
            return Observable.of(1);
        }, failed => {
            return Observable.of(0);
        });
}

private save4(saveObject: any): Observable<int> {
    this.api.save4(saveObject)
        .subscribe(successful => {
            return Observable.of(1);
        }, failed => {
            return Observable.of(0);
        });
}

Inside each of those save{number} functions I have log messages so I know exactly the order that these functions get executed (and responses come back). 在每个save{number}函数的内部,我都有日志消息,因此我确切地知道这些函数的执行顺序(然后返回响应)。

When I click save, it [almost] immediately redirects to my confirmation page, then I can sit there and watch my console window in chrome dev tools, and see the responses from the API calls start to come in. 当我单击保存时,它几乎立即重定向到我的确认页面,然后我可以坐在那儿并在chrome开发工具中观看控制台窗口,然后看到来自API调用的响应开始出现。

Why is this setup not accepting the explicit chaining of these transactions? 为什么此设置不接受这些事务的显式链接? I know in Angular 1, it was very easy to do this with the promise , and doing a .then(response => {}); 我知道在Angular 1中,很容易用promise做到这一点,然后执行.then(response => {}); .

The only thing that I can think of that is different, is for EVERY API call, whether it's a get / post / put / delete , it always shows 2 calls in the network panel of chrome dev tools. 我唯一想到的是不同的是,对于每个API调用,无论是get / post / put / delete ,它始终在chrome dev工具的网络面板中显示2个调用。 The first call has the RequestMethod set to Options , while the subsequent call is the corresponding get / post / put / delete with the RequestMethod set accordingly. 第一个调用将RequestMethod设置为Options ,而随后的调用是相应的get / post / put / delete并相应地设置了RequestMethod

I don't remember ever seeing those (duplicated calls) in any of my recent applications I've worked on, (maybe I just never paid attention as much) so maybe that's just the standard-operating-procedure for API calls. 我不记得在我最近开发的任何应用程序中都看到过这些(重复的调用),(也许我从来没有那么关注过),所以也许这只是API调用的标准操作过程。

Any ideas here? 这里有什么想法吗?

Edit: In response to Harry's suggested answer below 编辑:回应下面哈利的建议答案

I'm trying to implement your answer, but still a little confused on how to implement, here's a closer look at my setup: 我正在尝试实现您的答案,但是在实现方法上还是有些困惑,下面是我的设置的详细信息:

private save1(saveObject: any): Observable<number> {
    if (saveObject.hasChanges()) {
        return this.api.save1(saveObject)
            .map(successful => {
                return this.parseSaveResponse(successful, saveObject, true); // true indicates a successful API response
            })
            .catch(failed => {
                return this.parseSaveResponse(successful, saveObject, false); // false indicates a successful API response
            });
    } else {
        return Observable.of(-1); // no changes necessary, return immediately
    }
}

private parseSaveResponse(response: any, saveObject: any, transactionSuccessful: boolean) {
    this.logService.logTransaction({transactionType}, saveObject, response, transactionSuccessful);

    if (!transactionSuccessful) {
        // add to error list object to be displayed on the form
        return 0;
    }

    return 1;
}

When getting it to this point, it's throwing me an error on the .catch({}); 当到达这一点时,它在.catch({});上抛出了一个错误.catch({}); line saying: 行说:

Argument of type '(error: any) => 0 | 类型'(错误:任何)=> 0 |的参数 1' is not assignable to parameter of type '(err: any, caught: Observable<0 | 1>) => ObservableInput<{}>'. 1'不能分配给类型'(err:any,catched:Observable <0 | 1>)=> ObservableInput <{}>'的参数。 Type '0 | 输入'0 | 1' is not assignable to type 'ObservableInput<{}>'. 1'不可分配给'ObservableInput <{}>'类型。 Type '0' is not assignable to type 'ObservableInput<{}>'.) 无法将类型“ 0”分配给类型“ ObservableInput <{}>”。)

Theres quite a few issues with your code which might be contributing. 您的代码可能存在很多问题。 Firstly your save1/save2/save3 methods should just return the observable from your API which you will be able to subscribe to. 首先,您的save1 / save2 / save3方法应该只从您可以订阅的API中返回observable。

Secondly you're using the int type which doesn't exist in Typescript. 其次,您正在使用Typescript中不存在的int类型。 Use number . 使用编号

private save1(saveObject: any): Observable<number> {
  return this.api.save1(saveObject);
}
// or
private save1(saveObject: any): Observable<number> {
  return this.api.save1(saveObject).map(response => 1).catch(response => 0)
}

If you wanted to modify the items emitted you could add the map operator which maps the item emitted to something else. 如果要修改发出的项目,可以添加map运算符,该运算符将发出的项目映射到其他对象。

Lastly you should avoid subscribing to an observable from within an observable. 最后,您应该避免从可观察对象内部订阅可观察对象。 You can chain observables together using the flatMap operator. 您可以使用flatMap运算符将可观察对象链接在一起。 This transforms the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable. 这会将可观察对象发射的项目转换为可观察对象,然后将这些对象的发射平化为单个可观察对象。

save() {
  this.save1(saveObject1)
    .flatMap(response1 => this.save2(saveObject2))
    .flatMap(response2 => {
      if (response2 === 0) {
        // handle error
      }
      return this.save3(saveObject3);
    })
    .flatMap(() => this.save4(saveObject4))
    .subscribe(response4 => {
      // do redirect
    });
  }

http://reactivex.io/documentation/operators/flatmap.html http://reactivex.io/documentation/operators/flatmap.html

I think you need to "return" your observables. 我认为您需要“返回”您的观测值。 Ex: 例如:

Change this: 更改此:

this.api.save1(saveObject)

To: 至:

return this.api.save1(saveObject)

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

相关问题 等待 API 在 Angular 中完成 - Waiting for API to finish in Angular 为什么我的Angular 6按钮不会起波纹? - Why aren't my Angular 6 buttons rippling? Angular 7 - 如何强制 API 调用等待 HTTPInterceptor 完成,然后再进行其他 API 调用? - Angular 7 - How do I force API calls to wait for HTTPInterceptor to finish before making additional API calls? Angular - 等待后端调用完成而不是跳过 - Angular - Waiting for backend call to finish and not skip angular 用于循环进行 http 调用 - 等待上一个调用完成,然后再进行下一个 - angular for loop making http call - wait for previous call to finish before making next 为什么 Javascript/Angular 不让这个函数在它继续运行之前完成? - Why doesn't Javascript/Angular let this function finish before it continues on? 如何使 API 在 for 循环中调用以等待一个完成,然后再使用 observables 在 Angular 中创建另一个? - How to make API calls inside a for loop to wait for one to finish before making another in Angular using observables? Angular - 在转发请求之前等待刷新令牌 function 完成 - Angular - Waiting for refresh token function to finish before forwarding the request 等待可观察的完成-Angular - Waiting for observable to finish - Angular 等待订阅在Angular中完成 - Waiting for Subcription to finish in Angular
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM