В настоящее время я пытаюсь вернуть массив объектов JSON, который требует от меня выполнения одной асинхронной функции, а затем четырех вложенных асинхронных функций карты, чтобы заполнить массив сущностей. По сути, у каждого пользователя есть массив заказов, у каждого заказа есть массив элементов, у каждого элемента есть массив опций, и у каждой опции есть массив значений. Я использую инфраструктуру loopback4 и поэтому не могу выполнить res.send, как только все будет заполнено. Кажется, что функция возвращается при первом ожидании, но любое ожидание после этого не ждет, а вместо этого выполняется до конца функции. Я пытался использовать Promises и .thens(), но не могу понять, как заполнить каждый полностью вложенный объект, а затем вернуть массив заполненных объектов. Я продолжаю получать пустой массив. Ниже только одно гнездо карт, но я не могу заставить его даже заполниться до первого гнезда и вернуть это, поэтому я решил не идти дальше. Это код:
async getUserOrders2(@param.path.number('id') id: number): Promise<any> {
if ( !this.user) {
throw new HttpErrors.Unauthorized(AuthErrorKeys.ClientInvalid);
}
else if (this.user.id != id) {
throw new HttpErrors.Unauthorized(AuthErrorKeys.ClientInvalid);
}
else {
let restaurantId = this.user.restaurantId
let orderFrameArray = new Array<OrderFrame>()
return this.restaurantRepository.orders(restaurantId as string).find()
.then(async orders => {
orders.map(async (val, key)=> {
let orderFrame = new OrderFrame(val)
orderFrame.itemArray = await this.orderRepository.orderItems(val.id).find()
orderFrameArray.push(orderFrame)
})
orderFrameArray = await Promise.all(orderFrameArray)
return orderFrameArray
})
}
}
Функция возвращается до заполнения массива orderFrameArray. Мне нужно четыре вложенных цикла карт, и этот первый не работает, поэтому я не знаю, как сделать остальные. Любая помощь будет очень признательна.
Основываясь на решении @Tomalaks, я попробовал следующее, но он по-прежнему возвращает только массив верхнего уровня, и ничего не вложено:
async getUserOrders2(@param.path.number('id') id: number): Promise<any> {
if ( !this.user) {
throw new HttpErrors.Unauthorized(AuthErrorKeys.ClientInvalid);
}
else if (this.user.id != id) {
throw new HttpErrors.Unauthorized(AuthErrorKeys.ClientInvalid);
}
else {
let restaurantId = this.user.restaurantId
let orderFrameArray = new Array<OrderFrame>()
return this.restaurantRepository.orders(restaurantId as string).find()
.then(orders => {Promise.all(orders.map(
order => {
let orderFrame = new OrderFrame(order)
orderFrame.itemArray = new Array<Item>()
this.orderRepository.orderItems(order.id).find()
.then(orderItems => Promise.all(orderItems.map(
orderItem => {
let itemFrame = new Item(orderItem)
itemFrame.options = new Array<Option>()
this.orderItemRepository.orderItemOptions(orderItem.id).find()
.then(orderItemOptions => Promise.all(orderItemOptions.map(
orderItemOption => {
let optionFrame = new Option(orderItemOption)
optionFrame.values = new Array<Value>()
this.orderItemOptionRepository.orderItemOptionValues(orderItemOption.id).find()
.then(orderItemOptionValues => Promise.all(orderItemOptionValues.map(
orderItemOptionValue => {
let valueFrame = new Value(orderItemOptionValue)
optionFrame.values.push(valueFrame)})))
itemFrame.options.push(optionFrame)})))
orderFrame.itemArray.push(itemFrame)})))
orderFrameArray.push(orderFrame)}))
return orderFrameArray})
}
}
Прошу прощения за форматирование, я не был уверен, как лучше форматировать. Есть ли что-то еще, что я делаю неправильно?
Спасибо всем за ответ. Ответ, опубликованный @Tomalak, был правильным. Мне просто нужно было заключить всю функцию в скобки и поставить .then, чтобы вернуть заполненный объект, который я сделал
this.restaurantRepository.orders()
? Если функция возвращает фактические ордера, то.find()
каждый из них ненужно заново. Если функция не возвращает фактические заказы, она должна иметь другое имя. - person Tomalak   schedule 30.09.2019return
. Все обратные вызовы.map()
и некоторые обратные вызовы.then()
выше должны быть рассмотрены в этом отношении. - person Roamer-1888   schedule 30.09.2019.then()
обратных вызовов (где они существуют). Таким образом цепочка информируется о внутренней асинхронной активности. Таким образом, вы должны делать эти возвраты, даже если вы не доставляете данные таким образом. - person Roamer-1888   schedule 30.09.2019.map()
, иначе вы будете отображать массив неопределенных значений.Promise.all()
нужен массив промисов, чтобы укусить. - person Roamer-1888   schedule 30.09.2019