У меня есть система корзины покупок, где порядок запросов очень важен.Система должна иметь возможность создавать пользователей, прежде чем она добавит элементы в свою учетную запись.Для этого я использую обещания и пытаюсь связать их так, чтобы они появлялись одно за другим.Может быть, мое понимание неверно, но я не получаю это работать.
Функция ProcessUsers.Возвращает обещание.Порядок этой функции также важен, потому что нам нужно создать все учетные записи пользователей в порядке, прежде чем мы начнем соединять их вместе (в этой системе есть связь между ребенком и родителями)
this.createUsers иthis.createUserRelations - обе функции, которые возвращают список обещаний
processUsers(child, parents) {
return new Promise((resolve, reject) => {
Promise.all(
this.createUsers(child, parents)
).then((userResponse) => {
Promise.all(
this.createUserRelations(
child,
parents
)
).then((relationResponse) => {
resolve(relationResponse)
}).catch(reject)
}).catch(reject)
})
}
. Это работает.Порядок это правильный.Я проверяю это, заставляя функцию create_or_update на сервере спать в течение 5 секунд, и действительно функция createUserRelations ждет этого.
После того, как я создал пользователей, я использую ту же логику для добавления элементов каждому пользователю
/**
* process a single ticket
* @param {Array} ticket
*/
processTicket(ticket) {
var self = this
return new Promise((resolve, reject) => {
var ticketUser = {}
const userPromises = ticket.filter(
(t) => t.item.item_type === ITEM_TYPE_TICKET
).map((m) => {
ticketUser = m.user
return self.processUsers(m.user, m.parents)
})
const itemPromises = ticket.map(
(t) => {
if(t.item.item_type === ITEM_TYPE_BUS) {
t.user = ticketUser
}
return self.processItem(t)
}
)
Promise.all(userPromises).then((data) => {
Promise.all(itemPromises).then((data) => {
resolve(data)
}).catch(reject)
}).catch(reject)
})
}
Это не работает.ItemPromises не ждет завершения userPromises, и поэтому я получаю сообщение об ошибке, поскольку сервер не может найти пользователя, с которым связан элемент.Я знаю, что Promise.all () не запускает обещания в последовательном режиме, но я думал, что он запустит userPromises, и как только они будут решены, он запустит itemPromises.Кажется, он этого не делает.Я пробовал несколько других вещей, таких как использование p-очереди.
Вот функция processItem
processItem(item) {
// returns a Promise
return users.add_order_item(
this.sessionUser.id,
item.user.email,
item.item.id,
item.delivery
)
}
И, наконец, основная функция, обрабатывающая заявки на весь заказ
processOrder() {
const items = this.orderSessionItems
const reduced = this.groupBy(
items, (i) => i.reference_number)
var self = this
const promises = Object.keys(reduced).map((key, index) => {
return self.processTicket(reduced[key])
})
return Promise.all(promises)
}
ОБНОВЛЕНИЕ: Оказывается, я действительно неправильно понял, как работают Обещания.При отображении списка (два раза) в processTicket обещание processItem вызывается немедленно.Я думал, что это не тот случай, но он вызывается до того, как я выполняю Promise.all ().
В результате я получил
processTicket(ticket) {
return new Promise((resolve, reject) => {
var self = this
var ticketUser = {}
const userPromises = ticket.filter(
(t) => t.item.item_type === ITEM_TYPE_TICKET
).map((m) => {
ticketUser = m.user
return self.processUsers(m.user, m.parents)
})
Promise.all(userPromises).then(() => {
const itemPromises = ticket.map(
(t) => {
if(t.item.item_type === ITEM_TYPE_BUS) {
t.user = ticketUser
}
return self.processItem(t)
}
)
Promise.all(itemPromises)
.then((data) => resolve(data))
.catch(reject)
}).catch(reject)
})
}
и теперь он работает!