Петля с ожиданием

Я хочу запустить следующий код:

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 Синтаксис - это просто удобный способ сказать "подождите, пока закончится это обещание, прежде чем продолжить выполнение этой функции, пожалуйста"

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