2016-09-27 1 views
0

Grundsätzlich habe ich Aufrufe an verschiedene gespeicherte SQL-Prozeduren, die Versprechen zurückgeben. Normalerweise würden diese in zufälligen Reihenfolgen beginnen/enden, da sie asynchron sind. Ich muss die Reihenfolge kontrollieren, in der jede Prozedur aufgerufen wird.Achten Sie auf die Versprechung der Versprechung und dann auf die nächste Versprechung. Beobachtbar gegen Versprechen?

ich versucht habe .then() auf dem callCustomerIUD Versprechen mit, aber this._dataService.customerIUD(...).then(...) läuft erst nach callCustFieldIUD(), so customerFieldIUDthis.key bekommt als 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(...); 
} 

Ich habe Observables berücksichtigt, kann ich sie in diesem Fall verwenden? Hier ist meine data.service.ts Methoden Referenz oben. Sollten das Observable sein und nicht Promises?

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

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

Observablen Im Allgemeinen kann die Arbeit erledigen, die ES6 Versprechen tun. Ich bin mir nicht sicher, was genau in Ihren Methoden passiert, aber möglicherweise könnten RxJS-Operatoren hilfreich sein. – estus

+0

Ich bin neu bei Observablen. Denkst du, wenn ich die "Promise" -Typen auf "Observable" ändere, kann ich rxjs-Operatoren für die Observables verwenden? – jhhoff02

+1

Es ist nicht klar, ob "fooHttp" Ihr eigener Dienst oder der von Drittanbietern ist. Wenn sie Versprechungen zurückgibt, sollten sie mit dem Operator "fromPromise" in beobachtbar umgewandelt werden, oder der gesamte Dienst "fooHttp" sollte so geändert werden, dass Observables verwendet werden. – estus

Antwort

1

Ja, würde Observablen in diesem Szenario

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

Und im Dienst

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

weil die callCustFieldIUD() Funktion aufgerufen wird innerhalb der subscribe() groß sein Die von der Funktion callCustomerIUD() zurückgegebene Observable wird erst ausgeführt, wenn die Daten vorhanden sind.

(Dies kann nicht die genaue Code sein, das Sie brauchen. Ich bin mir nicht sicher, was wann geschehen muss, sondern auf Observablen und abonnieren Sie können strenger sein, wenn über Funktionen aufgerufen)

this helps

_______________ EDIT _________________________

ich glaube, Sie dies auch mit dem Versprechen erreichen kann, braucht nur eine leichte refactor

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

@ jhhoff02 Ich denke, es gibt auch eine vielversprechende Lösung. Siehe meine Bearbeitung über –

+0

Ich habe die Observable-Idee zusammen mit 'fromPromise()' wie estus oben vorgeschlagen – jhhoff02

1

Der Grund, warum Ihre erste Version nicht funktioniert, liegt darin, dass Ihr Programm weiterhin läuft und funktioniert, während die HTTP-Anfrage läuft. Eine Lösung besteht darin, die Ausführung von callCustFieldIUD zu erzwingen, nachdem der erforderliche Schlüssel festgelegt wurde. Das gleiche Problem würde auftreten und in ähnlicher Weise gelöst werden, wenn Sie Observables verwenden.

sollten Sie in der Lage sein zu tun:

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); 
    }); 
} 
Verwandte Themen