观察 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);
});
}
基本上我调用了 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);
});
}