【问题标题】:Why use async without await in Javascript?为什么在 Javascript 中使用 async 而不使用 await?
【发布时间】:2020-04-29 06:50:27
【问题描述】:

我见过很多人这样定义异步函数而不使用 await。

async function authMiddleware(req, res, next) => {
  try {
    const token = req.query.token
    const secret = process.env.JWT_SECRET
    jwt.verify(token, secret)
  } catch (err) {
    return res.status(403).json({ message: MESSAGES.TOKEN_EXPIRED })
  }
  return next()
}

我附上这段代码只是为了举例。请不要关心里面的线条的含义。

在 JavaScript 中没有任何 await 的情况下将函数定义为异步有什么好处或用例吗?

可能:他是否有可能打算通知用户它返回承诺?

【问题讨论】:

  • 看起来很奇怪。我能想到的唯一原因是他们是否计划很快在其中添加异步调用
  • 不,它是稳定的代码。他是否可能打算通知用户它返回承诺? @CertainPerformance
  • 这种情况完全没有意义,它只会让代码更难使用,更别提混淆了
  • 不,即使异步函数没有等待任何东西,该函数的使用者仍然会得到一个 Promise 作为回报,为了使用它,他们必须使用 .then 或 @ 987654324@
  • 一个已解决的承诺仍然是一个承诺。

标签: javascript node.js promise async-await


【解决方案1】:

ESLint 用它的规则 require-await 说了什么。

JavaScript 中的异步函数的行为与其他函数不同 在两个重要方面发挥作用:

  • 返回值始终是 Promise。
  • 您可以在其中使用 await 运算符。

使用异步函数的主要原因是 通常使用 await 运算符,...

MDN 说了什么:

异步函数声明定义了一个异步函数——一个 返回 AsyncFunction 对象的函数。异步函数 通过事件以与其余代码不同的顺序运行 循环,返回一个隐含的 Promise 作为其结果。但是语法和 使用异步函数的代码结构看起来像标准 同步函数。

很明显,异步函数不仅仅是为了等待使用。然后,在异步函数中没有等待是可以的。但是……有什么意义呢?

我相信它是使用像 Promise 这样的同步函数。以下示例来自javascript.info

async function f() {
  return 1;
}

f().then(alert); // 1

将与以下内容相同:

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1

将函数定义为异步有什么好处? javascript中的原因?

它可用于使代码更具可读性或易于理解。

结果客户端不会受到影响。

【讨论】:

    【解决方案2】:

    对于您显示的代码,它没有任何意义,因为它 - 至少我假设 - 一个 express 中间件,并且 expressjs 不使用该中间件返回的 Promise。在async中间件中没有await,唯一改变的是中间件返回Promise,并且由于expressjs不使用返回的Promise,所以这里的async关键字毫无意义,甚至可以有害的,如果 authMiddleware 中的内容抛出未缓存的错误。

    而且使用它没有意义without any reason。您可以使用asyncawait 将原本长时间运行的同步进程转换为更小的块,以便其他代码可以交错,因为await/async 允许您引入某种协作多任务处理。但仅将await/async 添加到长时间运行的任务中并不会阻止您阻塞事件循环。

    如果你有这样的代码:

    function testA() {
       for( let i=0 ; i<10 ; i++) {
          console.log('testA', i)
       }
    }
    
    function testB() {
    
       for( let i=0 ; i<10 ; i++) {
          console.log('testB', i)
       }
    }
    
    testA();
    testB();
    
    console.log('finished');

    然后您可以使用awaitasync 来允许其他代码交错,方法是将其更改为。

    async function testA() {
      for (let i = 0; i < 10; i++) {
        console.log('testA', await i)
      }
    }
    
    async function testB() {
    
      for (let i = 0; i < 10; i++) {
        console.log('testB', await i)
      }
    }
    
    Promise.all([
      testA(),
      testB()
    ]).then(() => {
      console.log('finished');
    })

    【讨论】:

    • 这不是我的代码,所以我想知道他使用异步而不使用内部等待的原因。是的,该功能是快速中间件,但我认为这并不重要
    • @think-serious 这很重要,因为如果代码执行异步函数对返回的Promise 执行任何操作,这很重要。 async 函数立即执行,它只在await 处暂停,并且由于不存在await,唯一发生的事情是返回了Promise,并且expressjs 对返回的Promise 不做任何事情。所以对于给定的代码,在这里放置async 没有任何意义。
    【解决方案3】:

    以上编写的代码旨在返回一个隐式 Promise 作为其 结果。

    喜欢

    async function firstFunction(a , b) {
       do some stuff here.....
    }
    function secondFunction(res){
     do some stuff here.....
    }
    async function thirdFunction(items){
     const data = await fetch('url here');
     const result = await data.json();
     do some stuff here........
    }
    

    所以这是交易....

    firstFunction(2,3) .然后((resOfFirst) => secondFunction(resOfFirst)) .那么((resOfSecond) => thirdFunction(resOfSecond))

    希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      对于提供的示例代码,我猜开发人员打算在将来使其异步(而不是阻塞事件循环),但他不知道这样做的简单方法。问题是jwt.verify 不提供基于Promise 的API,它接受可选的第三个回调参数,在这种情况下它将异步执行。再说一次我猜开发者对使用回调 API 没有信心,或者他一直对尽可能使用 async/await 充满信心。

      使用async/await 的可能解决方案可能是在该承诺函数调用上使用promisify jwt.verifyawait

      const verifyJwtAsync = Bluebird.promisify(jwt.verify);
      
      async function authMiddleware(req, res, next) => {
        try {
          const token = req.query.token
          const secret = process.env.JWT_SECRET
          await verifyJwtAsync(token, secret)
        } catch (err) {
          return res.status(403).json({ message: MESSAGES.TOKEN_EXPIRED })
        }
        return next()
      }
      

      一个更简单的基于回调的解决方案如下:

      async function authMiddleware(req, res, next) => {
          const token = req.query.token
          const secret = process.env.JWT_SECRET
          jwt.verify(token, secret, function(err) {
             if (err) res.status(403).json({ message: MESSAGES.TOKEN_EXPIRED });
             else next();
          })
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-10
        • 1970-01-01
        • 2021-03-01
        • 2015-06-30
        • 1970-01-01
        • 1970-01-01
        • 2019-04-05
        • 2023-01-17
        相关资源
        最近更新 更多