Попытка запустить импортированную асинхронную функцию в запросе получения API

Итак, в основном у меня есть два js-скрипта; один - маршрутизатор, сделанный с узлом и экспрессом:

import express from "express";
import showContent from "../model/model.js";

const router = express.Router();

//* Sends out the ejs (basically HTML) on start URL "localhost:8080"
router.get("/", function (req, res) {
  res.render("../pages/start.ejs");
});

//* Querys the database, the table ":id"
router.get("/:id", function (req, res, next) {
  id = req.params.id;
  let sqlQuery = `SELECT page_content FROM ${id} WHERE page_name = "about";`;
  console.info("1", showContent(sqlQuery));
  res.send(showContent(sqlQuery));

  next();
});

export default router;

а другой — скрипт с асинхронной функцией, извлекающей данные из моей базы данных SQLite:

import sqlite3 from "sqlite3";

const db = new sqlite3.Database(
  "path/to/my/db"
);

export default function getContent(sqlQuery, whenloaded) {
  return new Promise((resolve) => {
    resolve(
      db.all(sqlQuery, [], (err, rows) => {
        if (err) {
          console.error(err);
        } else {
          rows.forEach((row) => {
            whenloaded(row.page_content);
          });
        }
      })
    );
  });
}

async function showContent(sqlQuery) {
  await getContent(sqlQuery, (result) => {
    console.info("Result:", result);
  });
}

Вывод в моем браузере {} и журналы консоли, которые я получаю: 1 Promise { <pending> }, Result: "my content" и Result "my content".

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

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
85
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В вашем коде 3 проблемы.

Во-первых, вы не ждете завершения асинхронной функции showContent. Вот почему вы получаете сообщение об ожидающем промисе. Я советую вам прочитать промисы, чтобы лучше понять асинхронный код Javascript. Вкратце: промисы — это основное средство, на котором строится асинхронная функциональность.

Чтобы устранить эту проблему, обновите код маршрутизатора, чтобы дождаться функции showContent перед отправкой ответа:

router.get("/:id", async function (req, res, next) {
  const id = req.params.id;
  const sqlQuery = `SELECT page_content FROM ${id} WHERE page_name = "about";`;
  const content = await showContent(sqlQuery);
  console.info("1", content);
  res.send(content);

  next();
});

Вторая проблема заключается в том, что вы экспортируете функцию default и функцию showContent из файла модели. Однако вы используете оператор импорта:

import showContent from "../model/model.js";

Который импортирует экспорт файла model.js по умолчанию, в вашем случае функцию getContent, и присваивает его локальной переменной showContent. Я предполагаю, что вам действительно нужна функция showContent, поэтому вам следует обновить оператор импорта до (обратите внимание на фигурные скобки):

import { showContent } from "../model/model.js";

Третья проблема связана с асинхронным кодом в вашем файле модели. Во-первых, функция showContent ничего не возвращает. Следовательно, ожидание результата даст undefined. Во-вторых, вам следует реструктурировать функцию getContent, чтобы вам не понадобился обратный вызов whenLoaded, правильно используя силу промисов. Обновите код модели до:

import sqlite3 from "sqlite3";

const db = new sqlite3.Database(
  "path/to/my/db"
);

export function showContent(sqlQuery) {
  return new Promise((resolve, reject) => {
      db.all(sqlQuery, [], (err, rows) => {
        if (err) {
          reject(err);
        } else {
          resolve(rows);
        }
      });
  });
}

Я удалил теперь избыточную функцию showContent и переименовал функцию getContent в showContent, чтобы ваш ранее обновленный оператор импорта все еще работал. Конечно, вы всегда можете обновить имя и снова ввести экспорт по умолчанию (но не забудьте удалить фигурные скобки из оператора импорта, если вы это сделаете).

Спасибо, звучит вполне разумно, но содержание теперь не определено...?

pontaLainen 25.11.2022 16:53

Ах да, мой плохой. Это потому, что вы ничего не возвращаете из функции showContent. я обновлю свой ответ

thomaux 25.11.2022 16:54

Я как ребенок в рождественское утро, только и ждущий, чтобы открыть мои подарки!

pontaLainen 25.11.2022 16:56

Спасибо вам огромное, огромное!! Вы не представляете, как долго я сидел с этим, пытаясь понять это. Ты герой!!

pontaLainen 25.11.2022 17:26

С удовольствием, рад, что смог быть полезен

thomaux 28.11.2022 13:16

Другие вопросы по теме