javascript - 在 Async/Await 下留下无用的同步代码是一种反模式吗?

标签 javascript async-await event-loop

据我了解,await 背后的要点正如 Jake Archibald 解释的 here 是“等待”对 promise 的已解决值采取行动,直到它作为微任务遇到。 .
This video by LLJS表明 async-await 本质上是生成器运行器/解释器函数的语法糖,它产生它等待的位置并将 promise 的确定值传递给 .next()方法。这意味着 runner 的执行 .next()当等待发生时作为微任务排队。
实际上,await 下的所有代码只会在下一个微任务检查点执行。如果不需要等待的 promise 值的代码位于其下方,这可能是一个问题,这正是异步 IIFE 的问题。

async function ping() {
  for (let i = 0; i < 5; i++) {
    let result = await Promise.resolve("ping");
    console.log(result);
  }

  console.log("Why am I even here?");
}
    
async function pong() {
  for (let i = 0; i < 5; i++) {
    let result = await Promise.resolve("pong");
    console.log(result);
  }

  console.log("I have nothing to do with any of this");
}
    
console.log("Let the games begin!");
ping();
pong();
console.log("Placeholder for code that is not related to ping pong");

在这个例子中,外部日志首先被记录为运行脚本任务的一部分,然后是已解决的 Promise 的值,按照它们在微任务队列中的排队顺序。在整个过程中,留在 for 循环下面的日志与循环无关,并且会不必要地暂停,直到各自函数体中的最后一个微任务出队列为止。
这正是我们使用 async 时发生的情况。虽然起到 IIFE 的作用。如果您有 await 下的代码这意味着同步执行,它必须不必要地等待,直到它上面的所有等待都已从微任务队列中 check out 。
如果有人盲目地将他们的整个快速路线包裹在 async 中,我可以看到这是一个问题。函数,它们会不必要地await解决某些 promise ,如数据库操作、发送电子邮件、读取文件等......那么为什么人们仍然这样做呢?
app.post('/forgotPwd', async (req, res) => {
  const {email, username} = req.body;

  if (!email) {
    res.status(400).json({error: "No username entered"});
    return;
  }

  if (!username) {
    res.status(400).json({error: "No email entered"});
    return;
  }

  const db = client.db();
  
  const user = await db.collection("Users").findOne({username: username, "userInfo.email": email});

  if (!user) {
    res.status(400).json({error: "Account not found"});
    return;
  }

  const authToken = await getAuthToken({id: user._id.toHexString()}, "15m");

  // Would probably send a more verbose email
  await sgMail.send({
    from: process.env.EMAIL,
    to: email,
    subject: 'Forgot Password',
    text: `Use this url to reset your password: http://localhost:5000/confirmation/passConf/${authToken}`,
  });

  res.json({error: ""});
});

最佳答案

如果您想要 async 中的内容同步运行的函数,确保它在第一个 await 之前在函数中。

So why do people still do this?


对于 SO 来说,这可能是一个离题的问题,因为它在很大程度上需要基于意见的答案,但它可能是 A)因为他们不希望该代码在上面的代码完成之前运行,或者 B)因为他们不明白async功能。

关于javascript - 在 Async/Await 下留下无用的同步代码是一种反模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65477718/

相关文章:

javascript - 调用 valueOf 时的操作顺序

c++ - 如何将新的 Qt 窗口与现有的 X 应用程序集成?

javascript - 我是否需要将 'return' 语句放在 'casper.then' block 中,以便父函数等待子函数完成执行?

javascript - iPad 版“ Firebug ”

javascript - 使用 yield 作为异步控制流有什么好处?

.net - ConfigureAwait(false) 与 ASP.NET Core 相关吗?

javascript - 如何在不离开页面的情况下更改浏览器中的 URL?

javascript - angularjs ui-sortable : cannot call methods on sortable prior to initialization; attempted to call method 'refresh'

javascript - react-native fetch async/await 响应过滤

iphone - 自定义事件循环和 UIKit 控件。苹果的事件循环有什么额外的魔力?