【问题标题】:Loop with await循环等待
【发布时间】:2017-08-17 04:52:38
【问题描述】:

我要运行以下代码:

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);,但这会阻止该过程。有没有更好的办法?

【问题讨论】:

  • async函数getEncodedLogs返回一个promise ...所以你要么await要么使用logs.then等待getEncodedLogs返回的promise解决
  • 不...等待承诺解决不会block the process
  • @JaromandaX 还有其他问题。就像getEncodedLogs中的logsDecoded.push不是异步的,但是它有async和Promise.all
  • 哦,是的,还有其他问题——这就是为什么 async/await 是一个糟糕的主意——它给一些人一种错误的感觉,即他们的异步代码已经转换为同步代码——这可能以某种方式“阻止进程”
  • “我是 ES7 新手,想运行以下代码” ES7 不支持 async/await。 ES2017 将。为什么这个函数是异步的:async (log) => {“在 getEncodedLogs() 返回数组之前调用” getEncodedLogs 返回一个承诺。 “但这会阻塞进程。”_ 哪个进程会被阻塞?

标签: javascript ecmascript-6 ecmascript-2017


【解决方案1】:

所以目前这个例子中没有任何东西实际上是异步的,也不需要涉及 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 只是一个普通数组,因此 map 中的异步函数实际上不是异步的。

【讨论】:

    【解决方案2】:

    getEncodedLogs(transaction.logs) 不会返回您的日志,它会在完成1 后返回一个 resolves 到您的日志的 Promise。让它按预期工作的最简单方法是添加一个.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 语法只是一种方便的方式,表示“请等待此承诺完成后再继续执行此函数”

    【讨论】:

    • + 只是一个脚注
    猜你喜欢
    • 2023-01-20
    • 2015-07-18
    • 2020-05-09
    • 1970-01-01
    • 2018-08-04
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 2015-03-13
    相关资源
    最近更新 更多