观察 Promise 完成,然后执行下一个 Promise。可观察与承诺?

Watch for Promise completion, then exec next Promise. Observable vs Promise?

基本上我调用了 SQL 承诺的不同 SQL 存储过程。通常这些会 begin/end 以随机顺序排列,因为它们是异步的。我需要控制调用每个过程的顺序。

我尝试在 callCustomerIUD 承诺中使用 .then(),但是 this._dataService.customerIUD(...).then(...) 直到 callCustFieldIUD() 之后才 运行,所以 customerFieldIUD 得到 this.key 作为 undefined.

saveChanges(record) {
   this.callCustomerIUD(record);
   this.callCustFieldIUD();
}

callCustomerIUD(record): Promise<any>{
   return this._dataService
        .customerIUD(...)
        .then(data => {
            //THIS KEY IS NEEDED FOR customerFieldIUD
            this.key = data[data.length-1].CustomerKey; 
        }, error => {
            console.log(error);
        });
}

callCustFieldIUD() : Promise<any>{
    //USES KEY FROM customerIUD
    this.fillCustomerField(this.key);
    return this._dataService.customerFieldIUD(...);
}

我已经考虑过 Observables,我可以在这种情况下使用它们吗? 这是我上面的 data.service.ts 方法参考。这些应该是 Observable 而不是 Promises 吗?

customerIUD(data: any) : Promise<any>{
    return this.fooHttp
        .postData(...);
}

customerFieldIUD(data: any) : Promise<any>{
    return this.fooHttp
        .postData(...);
}

是的,Observables 在这种情况下会很棒

saveChanges(record) {
   this.callCustomerIUD(record).take(1).subscribe((data: any) => {
     // Observables can be subscribed to, like a .then() on a promise
     // data will be the response from the http call
     this.callCustFieldIUD(data).take(1).subscribe();
   });
}

callCustomerIUD(record): Observable<any>{
   return this._dataService.customerIUD(...)
}

callCustFieldIUD(data: any) : Observable<any>{
    //USES KEY FROM customerIUD
    this.fillCustomerField(this.key);
    return this._dataService.customerFieldIUD(...);
}

并在服务中

customerIUD(data: any) : Observable<any>{
  return this.fooHttp.postData(...).map((res: any) => {
    return res.json();
  });
}

customerFieldIUD(data: any) : Observable<any>{
  return this.fooHttp.postData(...).map((res: any) => {
    return res.json();
  });
}

因为 callCustFieldIUD() 函数是在 callCustomerIUD() 函数返回的 observable 的 subscribe() 内部被调用的,所以在数据存在之前它不会执行。

(这可能不是您需要的确切代码。我不确定什么时候会发生什么,但是通过订阅可观察对象,您可以更严格地确定何时调用函数)

希望对您有所帮助

_______________ 编辑 _________________________

我相信你也可以用 promises 实现这个,只需要稍微重构一下

saveChanges(record) {
   this.callCustomerIUD(record);
}

callCustomerIUD(record): Promise<any>{
   return this._dataService
        .customerIUD(...)
        .then(data => {
            // Instead of setting an instance var here, pass it in to the callCustFieldIUD() function
            this.callCustFieldIUD(data[data.length-1].CustomerKey);
        }, error => {
            console.log(error);
        });
}

callCustFieldIUD(customerKey: any) : Promise<any>{
    //USES KEY FROM customerIUD
    this.fillCustomerField(this.key);
    return this._dataService.customerFieldIUD(...);
}

您的第一个版本不起作用的原因是您的程序在 http 请求正在进行时继续工作。一个解决方案是强制 callCustFieldIUD 的执行发生在它需要的键被设置之后。如果您使用 Observables,同样的问题会出现并以类似的方式解决。

你应该可以做到:

saveChanges(record) {
    this.callCustomerIUD(record);
}

callCustomerIUD(record): Promise<any>{
return this._dataService
    .customerIUD(...)
    .then(data => {
        //THIS KEY IS NEEDED FOR customerFieldIUD
        this.key = data[data.length-1].CustomerKey;
        // Call the method you need to execute after the key is guaranteed
        // to be set
        this.callCustFieldIUD();
    }, error => {
        console.log(error);
    });
}