How do I chain some promises (NodeJS) together to continually enhance and object with new data and return the final object at the end of the chain. ie:
return getOrder().then((order) => {
return StatusMachine.getStatus(order.orderId);
}.then((status) => {
// get status response
// how do I access the "Order" in the previous then
// so I can do something like
order.status = status;
return order;
}).then((order) => {
return Shipping.getTrackingNumber(order.orderId);
}).then((tracking) => {
order.trackingNumber = tracking;
return order
});
Goal here is to load an order, then query its status and add it to the order, then query its tracking number and add it to the order. Currently, I'm setting Order as a global variable so that I can access it from every then() function and then in the final then(), I'm simply returning the global Order variable. However, that doesn't feel right.
CodePudding user response:
To get order
& status
you need to wrap it with async
function like this.
getOrder()
.then(async (order) => { // <--
const status = await StatusMachine.getStatus(order.orderId) // <-- await for status
return { order, status }
})
.then(({ status, order }) => {
order.status = status
return Promise.resolve(order) // if you are going to chain `.then` again then you have to return promise (converting this to async function will also works)
})
//.....
But I high recommend going full async
, its much more readable and error handling becomes super easy
const getOrderWithMetadata = async () => {
const order = await getOrder()
const status = await StatusMachine.getStatus(order.orderId)
order.status = status
const tracking = await Shipping.getTrackingNumber(order.orderId)
order.trackingNumber = tracking
return order
}
or with Promise.all
const getOrderWithMetadataBetter = async () => {
const order = await getOrder()
const [status, tracking] = await Promsie.all([ // waits for both to complete, throws error if anyone of them fails.
StatusMachine.getStatus(order.orderId),
Shipping.getTrackingNumber(order.orderId),
])
order.status = status
order.trackingNumber = tracking
return order
}