Петля с ожиданием
Я хочу запустить следующий код:
const express = require('express');
const app = express();
app.post('/getTransaction', (req,res) => {
let transaction = getTransaction(req.body.id);
let logs = getEncodedLogs(transaction.logs);
console.log('SEND'); // Gets called before getEncodedLogs() returns Array
return res.send(Object.assign(transaction, { logs }));
});
async function getEncodedLogs(logs) {
let logsDecoded = [];
await Promise.all(logs.map(async (log) => {
logsDecoded.push({
logIndex: log.logIndex,
data: log.data,
topics: log.topics
});
}));
console.log(logsDecoded);
return logsDecoded;
}
app.listen(process.env.PORT || 8000);
У меня проблема в том, что res.send(Object.assign(transaction, { logs }));
запускается раньше getEncodedLogs()
вернул обработанный Array
, Я мог бы переписать это let logs = await getEncodedLogs(transaction.logs);
но это заблокирует процесс. Есть ли способ лучше?
2 ответа
Так что в настоящее время в этом примере ничего не является асинхронным и не требует подключения к Promise. getTransactions может, но не видя реализации, я не могу сказать. Поэтому ответ может быть представлен так
const express = require('express');
const app = express();
app.post('/getTransaction', (req,res) => {
let transaction = getTransaction(req.body.id);
let logs = getEncodedLogs(transaction.logs);
console.log('SEND'); // Gets called before getEncodedLogs() returns Array
return res.send(Object.assign(transaction, { logs }));
});
function getEncodedLogs(logs) {
return logs.map((log) => {
return {
logIndex: log.logIndex,
data: log.data,
topics: log.topics
};
}));
}
app.listen(process.env.PORT || 8000);
Если мы погрузимся глубже и посмотрим на следующую часть вопроса
let logsDecoded = [];
await Promise.all(logs.map(async (log) => {
logsDecoded.push({
logIndex: log.logIndex,
data: log.data,
topics: log.topics
});
}));
logDecoded - это просто обычный массив, и поэтому асинхронная функция в карте на самом деле не асинхронная.
getEncodedLogs(transaction.logs)
не возвращает ваши журналы, он возвращает Обещание, которое разрешается в ваших журналах после его завершения 1. Простейшим способом заставить это работать как ожидалось было бы добавить .then
Перезвоните:
app.post('/getTransaction', (req, res) => {
let transaction = getTransaction(req.body.id);
getEncodedLogs(transaction.logs).then(logs => {
console.log('SEND');
res.send(Object.assign(transaction, { logs }));
});
});
1. как и все async
функции делают - await
Синтаксис - это просто удобный способ сказать "подождите, пока закончится это обещание, прежде чем продолжить выполнение этой функции, пожалуйста"