У меня есть следующий код.
public async getOrderInforAsync(customerOrderId) {
return new Promise((resolve, reject) => {
this.orderEntryService.getCommissionIncentives(customerOrderId)
.subscribe(
response => {
Object.assign(this.order, response);
this.order.bookingDate = this.order.bookingDate ? new Date(this.order.bookingDate) : null;
this.order.estBillDate = this.order.estBillDate ? new Date(this.order.estBillDate) : null;
this.order.orderSplit.forEach(element => {
element.rcNumberFullName = `${this.order.customerOrderRCNumber}${element.rcNumberSuffix}`;
});
this.initialQuantityAllocated();
this.orderSummary.allocatedEstCommissionPercent = this.calculateTotalOrderPercent();
this.orderSummary.allocatedEstCommissionAmount = this.calculateTotalOrderAmount();
this.highlight = this.checkOrderSummary(this.orderSummary.allocatedEstCommissionPercent, this.orderSummary.allocatedEstCommissionAmount);
this.calculateAllocatedActualPercent();
this.calculateAllocatedActualAmount();
this.onChangeEstSalesPrice();
resolve();
},
error => {
reject();
}
);
});
}Иногда метод resolve () вызывается до выполнения this.calculateAllocatedActualPercent () и this.calculateAllocatedActualAmount (). Итак, как заставить этот код работать синхронизированным, это означает, что все функции в этом блочном коде были выполнены до вызова метода resolve ()?
Привет, SiddAjmera, эта функция вызывается из другой функции с другим API, поэтому я хочу, чтобы этот код был выполнен перед вызовом другой функции.
@PHONGDN, this.calculateAllocatedActualPercent() и this.calculateAllocatedActualAmount() возвращают Promise?
@SiddAjmera Нет, это нормальная функция.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Функция async возвращает Promise. А чтобы объявить функцию как async, вам нужно иметь внутри нее вызов await.
Измените наблюдаемый объект, возвращенный из this.orderEntryService.getCommissionIncentives(customerOrderId), .toPromise(), а затем его await.
Попробуй это:
public async getOrderInforAsync(customerOrderId) {
try {
const response = await this.orderEntryService
.getCommissionIncentives(customerOrderId).toPromise();
this.order = { ...response };
this.order.bookingDate = this.order.bookingDate ? new Date(this.order.bookingDate) : null;
this.order.estBillDate = this.order.estBillDate ? new Date(this.order.estBillDate) : null;
for (let i = 0; i < this.order.orderSplit; i++) {
const element = this.order.orderSplit[i];
element.rcNumberFullName = `${this.order.customerOrderRCNumber}${element.rcNumberSuffix}`
}
this.initialQuantityAllocated();
this.orderSummary.allocatedEstCommissionPercent = this.calculateTotalOrderPercent();
this.orderSummary.allocatedEstCommissionAmount = this.calculateTotalOrderAmount();
this.highlight = this.checkOrderSummary(this.orderSummary.allocatedEstCommissionPercent, this.orderSummary.allocatedEstCommissionAmount);
this.calculateAllocatedActualPercent();
this.calculateAllocatedActualAmount();
this.onChangeEstSalesPrice();
return response;
} catch (error) {
return error;
}
}
exportPDF () {this.reviewComponent.getOrderInforAsync (). then (() => {this.export ();}); } мой код в других компонентах. Я хочу, чтобы все функции выполнялись для привязки всего html, а затем экспорта из html в pdf. Но иногда какая-то функция в блоке вопросов еще не выполнена. Так что html генерируется недостаточно.
@PHONGDN, это будет означать, что помимо вызова метода this.orderEntryService.getCommissionIncentives(customerOrderId) есть еще один асинхронный вызов в методе getOrderInforAsync. Но вы сказали, что их нет. Так что вы можете пролить свет на это. Можно создать образец stackblitz, воспроизводящий вашу проблему.
@SiddAjmere Экспорт в pdf вызовите getOrderInforAsync () -> render html -> после этого вызовите exportPDF (). «Можно создать образец stackblitz, воспроизводящий вашу проблему» Мой продукт довольно большой, поэтому, возможно, я не смогу создать для вас другой код обзора, такой как stackblitz.
Попробуй это :
public async getOrderInforAsync(customerOrderId) {
return new Promise((resolve, reject) => {
this.orderEntryService.getCommissionIncentives(customerOrderId)
.subscribe(
response => {
Object.assign(this.order, response);
this.order.bookingDate = this.order.bookingDate ? new Date(this.order.bookingDate) : null;
this.order.estBillDate = this.order.estBillDate ? new Date(this.order.estBillDate) : null;
this.order.orderSplit.forEach(element => {
element.rcNumberFullName = `${this.order.customerOrderRCNumber}${element.rcNumberSuffix}`;
});
this.initialQuantityAllocated();
this.orderSummary.allocatedEstCommissionPercent = this.calculateTotalOrderPercent();
this.orderSummary.allocatedEstCommissionAmount = this.calculateTotalOrderAmount();
this.highlight = this.checkOrderSummary(this.orderSummary.allocatedEstCommissionPercent, this.orderSummary.allocatedEstCommissionAmount);
await this.calculateAllocatedActualPercent();
await this.calculateAllocatedActualAmount();
this.onChangeEstSalesPrice();
resolve();
},
error => {
reject();
}
);
});
}
async calculateAllocatedActualPercent(){
return new Promise(resolve,reject){
// call api
if (data)
resolve(data);
else
reject()
}
}
async calculateAllocatedActualAmount(){
return new Promise(resolve,reject){
// call api
if (data)
resolve(data);
else
reject()
}
}
Предупреждаем, forEach не будет работать с функцией async. Вам придется заменить его на обычный шлейф for. Кроме того, как прокомментировал OP, calculateAllocatedActualPercent и calculateAllocatedActualAmount являются обычными функциями и не возвращают Promise.
@ Сартак Аггарвал, я хочу решить (); вызывается последним, потому что у меня есть этот код exportReviewPdf () {getOrderInforAsync (). then (() => {export ();}}
@SiddAjmera Спасибо! Я этого не знал. Но, чтобы прояснить, forEach не работает, если у меня есть асинхронный код внутри forEach, но мы можем иметь forEach внутри вызова async?
@PHONGDN вы можете поделиться exportReviewPdf() и как вы это называете?
Я вызываю эту функцию после порядка редактирования и автоматического экспорта в pdf.
Являются ли
this.calculateAllocatedActualPercent()иthis.calculateAllocatedActualAmount()асинхронными по своей природе? Они делают какие-либо вызовы API или что-то в этом роде? Если нет, то этот код должен работать синхронно.