Из базового выражения 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(...)?
Большое спасибо за любые советы.
Вы можете использовать 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(...)
независимо от того, ваша функция больше не будет бросать или ошибочно синхронно после того, как будут задействованы обещания.
Любая функция 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);
});
.then()
с обратными вызовами обещаний вместо синтаксисаasync
/await
). Но почему вы этого хотите, у вас есть рабочее решение?