Включая результаты асинхронной функции в мое «возвращение» при отображении массива

#javascript #node.js #asynchronous #sequelize.js

Вопрос:

Проблема

Я пытаюсь вызвать функцию базы данных при отображении массива. Я создал несколько примеров кода, чтобы продемонстрировать свою проблему в меньшем масштабе. Я использую зависимости «mysql2» и «sequelize», а также MySQL Workbench.

Цель в примере кода

У меня в базе данных есть две таблицы — одна называется «ящики», а другая — «предметы». Каждый элемент будет находиться в коробке (у него будет свойство ‘box_id’). У каждой коробки есть свое местоположение. Я хочу получить массив объектов, в котором просто отображается имя элемента и расположение поля, в котором он находится (а не только идентификатор). Я хочу, чтобы это было сделано как можно более чистым способом. Я знаю, что есть способ связать две базы данных вместе, и ответ о том, как это сделать, был бы признателен, но я чувствую, что изучил бы более важные концепции, используя другой метод — поэтому в идеале я хотел бы альтернативное решение.

Код

Функция mainFunction() является отправной точкой

 // Gets all items currently in my database and returning the dataValues const getAllItems = async () =gt; {  const findAllItems = await Item.findAll()  const items = findAllItems.map(item =gt; item.dataValues)  return items }  // Gets a box from my database, by ID, and returning its dataValues const getOneBox = async (id) =gt; {  const findOneBox = await Box.findOne({ where: {id}})  return findOneBox.dataValues }  // Starting point const mainFunction = async () =gt; { // Get all items in database  const items = await getAllItems()  // Go through each item, and everytime, get the box that corresponds to the item's box_id  const myArray = items.map(async item =gt; {  const getBox = await getOneBox(item.box_id) // Return an object with my custom formatting, and including the box's location  return {  itemID: item.id,  itemName: item.name,  itemLocation: getBox.location  }  })  // The function will only work if I manually give my function enough time to finish  console.log('myArray before delay =gt; ', myArray)  await new Promise(response =gt; setTimeout(response, 500))  console.log('myArray after delay =gt; ', myArray) }  

Вот результат в моем терминале:

enter image description here

Setup

Here is my setup if it matters. I populated my tables manually to simplify things:

items =gt; Item

boxes =gt; Boxes

 // Populating the existing 'test' schema with relevant tables and running main function after connecting const Sequelize = require('sequelize') const database = new Sequelize ('test', 'root', [REDACTED], {  host: 'localhost',  dialect: 'mysql',  define: {  timestamps: false  } }) const connect = async () =gt; {  await database.authenticate()  .then(async () =gt; {  await database.sync()  console.log('Connected...')  mainFunction()  }).catch(error =gt; {  console.log('Failed to connect =gt; ', error)  }) } connect()   // Defining my models const Box = database.define('box', {  name: Sequelize.STRING,  location: Sequelize.STRING }) const Item = database.define('item', {  name: Sequelize.STRING,  box_id: Sequelize.INTEGER })   

Ответ №1:

Оказывается, проблема заключалась в моем подходе; на самом деле с циклами for все очень просто. Я оставлю свое решение на случай, если оно кому-нибудь поможет.

Это просто добавляет еще одно свойство в мой массив элементов

 const mainFunction = async () =gt; {  const items = await getAllItems()  for(i = 0; i lt; items.length; i  ) {  const getBox = await getOneBox(items[i].box_id)  items[i]['location'] = getBox.location  }  console.log(items) }  

введите описание изображения здесь

Это для того, чтобы я мог отформатировать его по-своему

 const mainFunction = async () =gt; {  const items = await getAllItems()  const itemsFormatted = []  for(i = 0; i lt; items.length; i  ) {  const getBox = await getOneBox(items[i].box_id)  itemsFormatted.push({  itemID: items[i].id,  itemName: items[i].name,  itemLocation: getBox.location  })  }  console.log(itemsFormatted) }  

введите описание изображения здесь