gpt4 book ai didi

javascript - Node.js - Promise 执行顺序问题

转载 作者:太空宇宙 更新时间:2023-11-04 03:30:03 24 4
gpt4 key购买 nike

我对异步操作的执行顺序有疑问。下面是我的代码,它向第三方 API 发送一个创建发票项目的请求,然后发送另一个创建发票的请求。我的问题是,发票是在创建调整发票项目之前创建的。

function createInvoiceItems(invoice, customerDetails) {
return new Promise((resolve, reject) => {
const invoiceItems = invoice.invoiceItems;
const invoiceCurrency = invoice.currency;

const promises = invoiceItems.map((invoiceItem) =>
new Promise((fulfill, deny) => {
invoiceItem.currency = invoiceCurrency;

createInvoiceItem(customerDetails, invoiceItem)
.then((item) => fulfill(invoiceItem.amount))
.catch((error) => deny(error));
})
);

return Promise.all(promises)
.then((lineTotals) => {
if (lineTotals.length > 0) {
const invoiceTotal = calculateInvoiceTotal(lineTotals);
console.log('INVOICE TOTALS ######################', invoiceTotal);
const customerCommitment = invoice.commitment;

//Create adjustment invoice item
if (invoiceTotal < customerCommitment) {
const adjustmentAmount = (customerCommitment - invoiceTotal);
console.log('ADJUSTMENT AMOUNT ######################', adjustmentAmount);
const invoiceItem = {
currency: invoiceCurrency,
amount: adjustmentAmount,
description: 'Adjustment',
};

createInvoiceItem(customerDetails, invoiceItem)
.then((item) => {
if (typeof item === 'object') {
return resolve(customerDetails.stripeId);
}
})
.catch((error) => reject(error));
}
}
})
.then(() => resolve(customerDetails.stripeId))
.catch((error) => reject(error));
});
}

/**
* Generates customer invoices
* @param invoices
*/
function generateInvoices(invoices) {
return new Promise((resolveInvoice, rejectInvoice) => {
const promises = invoices.map((invoice) =>
new Promise((resolve, reject) => {
let invoiceDetails;

getInvoice(invoice)
.then((invoiceObject) => {
invoiceDetails = invoiceObject;
return getCustomerDetails(invoiceDetails.customerId);
})
.then((customerDetails) => createInvoiceItems(invoiceDetails, customerDetails))
.then((customerId) => createInvoice(customerId))
.then((thirdPartyInvoice) => {
invoiceDetails.close = true;

updateInvoiceFile(invoiceDetails)
.then(() => resolve(thirdPartyInvoice.id));
})
.catch((error) => reject(error));
})
);

Promise.all(promises)
.then((invoice) => {
if (invoice.length > 0) {
return resolveInvoice(invoice);
}
return rejectInvoice('Invoice could not be generated');
})
.catch((error) => rejectInvoice(error));
});
}

这段代码有什么问题?

最佳答案

发生这种情况是因为以下构造:

.then(… => {

createInvoiceItem(customerDetails, invoiceItem)
.then(… => {
resolve(customerDetails.stripeId);
})
})
.then(() => resolve(…))

由于您没有从第一个回调中返回任何内容,因此 promise 链不会等待任何内容,并在第二个回调中立即调用resolvecreateInvoiceItem 之后调用的 resolve 来得太晚了。

但您真正的问题是 Promise constructor antipattern 的普遍使用。您不得在任何地方使用 Promise 构造函数 - then 链!这大大简化了您的代码:

function createInvoiceItems(invoice, customerDetails) {
const invoiceItems = invoice.invoiceItems;
const invoiceCurrency = invoice.currency;

const promises = invoiceItems.map(invoiceItem => {
invoiceItem.currency = invoiceCurrency;
return createInvoiceItem(customerDetails, invoiceItem)
.then(item => invoiceItem.amount);
});

return Promise.all(promises)
.then(lineTotals => {
if (lineTotals.length > 0) {
const invoiceTotal = calculateInvoiceTotal(lineTotals);
console.log('INVOICE TOTALS ######################', invoiceTotal);
const customerCommitment = invoice.commitment;

//Create adjustment invoice item
if (invoiceTotal < customerCommitment) {
const adjustmentAmount = (customerCommitment - invoiceTotal);
console.log('ADJUSTMENT AMOUNT ######################', adjustmentAmount);
const invoiceItem = {
currency: invoiceCurrency,
amount: adjustmentAmount,
description: 'Adjustment',
};

return createInvoiceItem(customerDetails, invoiceItem)
.then(item => {
if (typeof item === 'object') {
return customerDetails.stripeId;
}
// not sure what should happen otherwise?
});
}
} // else
return customerDetails.stripeId;
});
}

function generateInvoices(invoices) {
const promises = invoices.map(invoice =>
getInvoice(invoice)
.then(invoiceObject =>
getCustomerDetails(invoiceDetails.customerId);
.then(customerDetails => createInvoiceItems(invoiceDetails, customerDetails))
.then(customerId => createInvoice(customerId))
.then(thirdPartyInvoice => {
invoiceObject.close = true;
return updateInvoiceFile(invoiceDetails)
.then(() => thirdPartyInvoice.id);
})
)
);

return Promise.all(promises)
.then(invoice => {
if (invoice.length > 0)
return invoice;
else
throw new Error('Invoice could not be generated');
});
}

关于javascript - Node.js - Promise 执行顺序问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39342437/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com