如何一个接一个地调用异步函数?
How to call one asynchronous function after another?
这是我的:
ngOnInit() {
this._addServ.getDefaultAddress().subscribe((res)=>{
if(res.status){
//I need these next two functions to finish their async API requests
//before selectNormalDelivery is called
this.selectShippingAddress();
this.selectBillingAddress();
this.selectNormalDelivery();
}
})
}
我需要 selectShippingAddress
和 selectBillingAddress
完成他们的呼叫,然后 selectNormalDelivery
才能被呼叫。我怎样才能做到这一点?我不想将它们转换为承诺,因为它们在其他时候被调用而无需链接。这是涉及.then
的东西吗?
这是函数的代码:
selectShippingAddress(){
this.addressService.setShippingAddresses(this.cartService.shippingAddress.address_id).subscribe((res) => {
console.log('Set shipping address!')
console.log(res);
}, err => {
console.log('Failed to set shipping address')
console.log(err);
})
}
selectBillingAddress(){
this.addressService.setPaymentAddresses(this.cartService.billingAddress.address_id).subscribe((res) => {
console.log('Set billing address!')
console.log(res);
}, err => {
console.log('Failed to set billing address')
console.log(err);
})
}
如果我尝试 .then
,我会得到错误 Property 'then' does not exist on type 'void'.
,这是有道理的,因为我没有尝试 return 任何东西,我只需要他们完成他们的电话为了 API 的缘故。
建议?
ngOnInit() {
this._addServ.getDefaultAddress().subscribe((res)=>{
if(res.status){
//I need these next two functions to finish their async API requests
//before selectNormalDelivery is called
forkJoin([this.selectShippingAddress(),this.selectBillingAddress()].subscribe(() => {
this.selectNormalDelivery();
});
}
})
}
selectShippingAddress(){
return this.addressService.setShippingAddresses(this.cartService.shippingAddress.address_id).pipe(map((res) => {
console.log('Set shipping address!')
console.log(res);
}, err => {
console.log('Failed to set shipping address')
console.log(err);
}));
}
selectBillingAddress(){
return this.addressService.setPaymentAddresses(this.cartService.billingAddress.address_id).pipe(map((res) => {
console.log('Set billing address!')
console.log(res);
}, err => {
console.log('Failed to set billing address')
console.log(err);
}));
}
如果我没理解错的话,你需要监听一个 observable(来自 getDefaultAddress()
),然后处理另外两个 observable(this.addressService.setShippingAddresses()
和 this.addressService.setPaymentAddresses()
),然后调用函数 selectNormalDelivery()
.
您可以使用 RxJS switchMap
, catchError
, tap
operators and forkJoin()
来做到这一点。尝试以下
import { forkJoin, EMPTY } from 'rxjs';
import { tap, catchError, switchMap } from 'rxjs/operators';
ngOnInit() {
this._addServ.getDefaultAddress().pipe(
switchMap((res) => { // <-- map the observable from `getDefaultAddress()` to another observable
if(res.status) {
return forkJoin([ // <-- `forkJoin` emits only after the observables complete
this.selectShippingAddress(), this.selectBillingAddress()
])
}
})
).subscribe(response => {
this.selectNormalDelivery()
})
}
selectShippingAddress() {
return this.addressService.setShippingAddresses(this.cartService.shippingAddress.address_id).pipe(
tap((res) => { // <-- `tap` doesn't alter the response
console.log('Set shipping address!')
console.log(res);
}),
catchError((err) => { // <-- `catchError` must return an observable
console.log('Failed to set shipping address')
console.log(err);
return EMPTY;
}))
}
selectShippingAddress() {
return this.addressService.setPaymentAddresses(this.cartService.shippingAddress.address_id).pipe(
tap((res) => {
console.log('Set billing address!')
console.log(res);
}),
catchError((err) => {
console.log('Failed to set billing address')
console.log(err);
return EMPTY;
}))
}
这是我的:
ngOnInit() {
this._addServ.getDefaultAddress().subscribe((res)=>{
if(res.status){
//I need these next two functions to finish their async API requests
//before selectNormalDelivery is called
this.selectShippingAddress();
this.selectBillingAddress();
this.selectNormalDelivery();
}
})
}
我需要 selectShippingAddress
和 selectBillingAddress
完成他们的呼叫,然后 selectNormalDelivery
才能被呼叫。我怎样才能做到这一点?我不想将它们转换为承诺,因为它们在其他时候被调用而无需链接。这是涉及.then
的东西吗?
这是函数的代码:
selectShippingAddress(){
this.addressService.setShippingAddresses(this.cartService.shippingAddress.address_id).subscribe((res) => {
console.log('Set shipping address!')
console.log(res);
}, err => {
console.log('Failed to set shipping address')
console.log(err);
})
}
selectBillingAddress(){
this.addressService.setPaymentAddresses(this.cartService.billingAddress.address_id).subscribe((res) => {
console.log('Set billing address!')
console.log(res);
}, err => {
console.log('Failed to set billing address')
console.log(err);
})
}
如果我尝试 .then
,我会得到错误 Property 'then' does not exist on type 'void'.
,这是有道理的,因为我没有尝试 return 任何东西,我只需要他们完成他们的电话为了 API 的缘故。
建议?
ngOnInit() {
this._addServ.getDefaultAddress().subscribe((res)=>{
if(res.status){
//I need these next two functions to finish their async API requests
//before selectNormalDelivery is called
forkJoin([this.selectShippingAddress(),this.selectBillingAddress()].subscribe(() => {
this.selectNormalDelivery();
});
}
})
}
selectShippingAddress(){
return this.addressService.setShippingAddresses(this.cartService.shippingAddress.address_id).pipe(map((res) => {
console.log('Set shipping address!')
console.log(res);
}, err => {
console.log('Failed to set shipping address')
console.log(err);
}));
}
selectBillingAddress(){
return this.addressService.setPaymentAddresses(this.cartService.billingAddress.address_id).pipe(map((res) => {
console.log('Set billing address!')
console.log(res);
}, err => {
console.log('Failed to set billing address')
console.log(err);
}));
}
如果我没理解错的话,你需要监听一个 observable(来自 getDefaultAddress()
),然后处理另外两个 observable(this.addressService.setShippingAddresses()
和 this.addressService.setPaymentAddresses()
),然后调用函数 selectNormalDelivery()
.
您可以使用 RxJS switchMap
, catchError
, tap
operators and forkJoin()
来做到这一点。尝试以下
import { forkJoin, EMPTY } from 'rxjs';
import { tap, catchError, switchMap } from 'rxjs/operators';
ngOnInit() {
this._addServ.getDefaultAddress().pipe(
switchMap((res) => { // <-- map the observable from `getDefaultAddress()` to another observable
if(res.status) {
return forkJoin([ // <-- `forkJoin` emits only after the observables complete
this.selectShippingAddress(), this.selectBillingAddress()
])
}
})
).subscribe(response => {
this.selectNormalDelivery()
})
}
selectShippingAddress() {
return this.addressService.setShippingAddresses(this.cartService.shippingAddress.address_id).pipe(
tap((res) => { // <-- `tap` doesn't alter the response
console.log('Set shipping address!')
console.log(res);
}),
catchError((err) => { // <-- `catchError` must return an observable
console.log('Failed to set shipping address')
console.log(err);
return EMPTY;
}))
}
selectShippingAddress() {
return this.addressService.setPaymentAddresses(this.cartService.shippingAddress.address_id).pipe(
tap((res) => {
console.log('Set billing address!')
console.log(res);
}),
catchError((err) => {
console.log('Failed to set billing address')
console.log(err);
return EMPTY;
}))
}