Вызов асинхронной (Promise) функции из функции синхронизации с Express и Node

1

Из базового выражения index.js файла существует ли способ вызова функции асинхронного вызова из функции синхронизации (getData здесь)?

const express = require('express');
const bodyParser = require('body-parser');

// function which calls a Promise
const getData = require('./getAsyncData.js');

const app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.get('/authors/:lang', (req, res) => { 

  const lang = req.params.lang; 
  const getResults = getData( lang );
  res.json(getResults);

});

Вот как выглядит модуль getAsyncData:

// getAsyncData.js

const getAsyncData = async function () {

  try {

    // Questionable method of recovering the lang parameter here.
    const lang = (arguments.length) ? arguments[0].toUpperCase() : null;

    // Connect to the database
    const connection = await db.connect(true);

    // Get the data
    const {authors, books} = await connection.load();

    // Join results and filter it
    const filtered_results = GetAuhtorsBooks(authors, books, lang);

    // Send it back 
    return filtered_results;

  } catch(e) {

    return null;

  }

};

module.exports = getAsyncData;

Но в index.js вызов getData неизбежно возникает перед вызовами внутри модуля getAsyncData. getData дает undefined. Кажется, единственный способ получить результат - сделать что-то подобное в index.js:

app.get('/authors/:lang', async (req, res, next) => {

  try {
    const lang = req.params.lang;
    const testResult = await runTests(lang);
    res.json(testResult);

  } catch (e) {

    //this will eventually be handled by the error handling middleware
    next(e) 

  }

});

Есть ли способ получить тот же результат без реализации функции async/await в app.get(...)?

Большое спасибо за любые советы.

  • 0
    Нет, это невозможно. (Конечно, вы можете использовать вызовы .then() с обратными вызовами обещаний вместо синтаксиса async / await ). Но почему вы этого хотите, у вас есть рабочее решение?
  • 0
    Привет Берги, спасибо за ваш комментарий. Я не прошел тест, я хотел бы знать, почему. Не было возможности изменить index.js выше. Но модуль getAsyncData должен был вызвать Promise. Я попробовал все, что мог.
Показать ещё 6 комментариев
Теги:
express
async-await
asynchronous
promise

2 ответа

1

Вы можете использовать API нижнего уровня .then()

app.get('/authors/:lang', (req, res, next) => { 

  const lang = req.params.lang; 
  getData( lang )
    .then(getResults => res.json(getResults));
    .catch(next);

});

Но в этот момент вам лучше с async, особенно когда ваш код достигнет точки, когда просто получить одну точку данных и вернуть ее недостаточно, и вам нужно делать больше вещей.

Вам все равно придется вручную вызывать next() или res.error(...) независимо от того, ваша функция больше не будет бросать или ошибочно синхронно после того, как будут задействованы обещания.

0

Любая функция async всегда возвращает Promise. express поддерживает обработчики маршрутов, возвращающие обещания. Вы можете использовать этот код:

const express = require('express');
const bodyParser = require('body-parser');

// function which calls a Promise
const getData = require('./getAsyncData.js');

const app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.get('/authors/:lang', async (req, res) => { 

  const lang = req.params.lang; 
  const results = await getData( lang );
  res.json(results);

});

Ещё вопросы

Сообщество Overcoder
Наверх
Меню