了解NodeJS上的异步/等待

时间:2017-06-13 04:27:13

标签: javascript node.js asynchronous async-await

我认为我对它的理解可能会受到我对 .NET async/await的体验的影响,所以我想要一些代码示例:

我试图让快速控制器在返回响应前等待5秒钟:

const getUsers = async (ms) => {
  var wait = ms => new Promise(resolve => setTimeout(resolve, ms));

  await wait(ms);
};


export const index = (req, res) => {
  async () => {
    await getUsers(5000);

    res.json([
      {
        id: 1,
        name: 'John Doe',
      },
      { id: 2,
        name: 'Jane Doe',
      },
    ]);
  };
};

此代码不起作用,浏览器不断加载和加载,从不显示任何内容。

我基于this SO answer构建的getUser函数和控制器方法,基于我对其工作方式的错误理解,所以我想要一些澄清和纠正:

1。我应该何时使用await

据我了解,您应该在await函数调用之前使用async。它是否正确?另外,为什么我可以在返回promise的非异步函数之前调用await?

2。我应该何时使用async

据我了解,您将一个函数标记为async,以便可以使用await关键字调用它。它是否正确?另外,[为什么]我必须将await getUsers(5000)调用包装在匿名异步函数中?

3 个答案:

答案 0 :(得分:10)

澄清一些疑问 -

  1. 您可以将await与任何返回承诺的函数一起使用。您正在等待的功能不一定是async
  2. 如果要在该函数中使用async关键字,则应使用await函数。如果您不在函数内使用await关键字,则无需创建该函数async
  3. async函数默认返回一个promise。这就是您能够await async功能的原因。
  4. 来自MDN -

      

    当调用异步函数时,它返回一个Promise。

    就你的代码而言,它可以这样写 -

    const getUsers = (ms) => { // No need to make this async
        return new Promise(resolve => setTimeout(resolve, ms));
    };
    
    // this function is async as we need to use await inside it
    export const index = async (req, res) => {
        await getUsers(5000);
    
        res.json([
          {
            id: 1,
            name: 'John Doe',
          },
          { id: 2,
            name: 'Jane Doe',
          },
        ]);
    };
    

答案 1 :(得分:3)

您可以在await函数中async承诺awaitDriverSchema.index({ "geometry": "2dsphere"}); 之后的代码将在您等待完成的承诺之后执行。

这是经典JavaScript回调的绝佳替代方案。

我写了一篇关于它的博客 - > https://github.com/Gameye/js-async我希望这会对你有帮助!

答案 2 :(得分:1)

async await只是承诺的语法糖。

当你希望你的代码在完成一个函数的情况下运行时,就像使用promises一样使用它们。

async function asyncOperation(callback) {
    const response = await asyncStep1();
    return await asyncStep2(response);
}
如果使用promises land语法,那么

就是确切的事情:

function asyncOperation() {
  return asyncStep1(...)
    .then(asyncStep2(...));
}

新的async / await语法允许您仍然使用Promises,但它不需要为链式then()方法提供回调。

而是直接从异步函数返回回调,就好像它是同步阻塞函数一样。

let value = await myPromisifiedFunction(); 

当你计划在你的函数中使用await时,你应该用async关键字标记你的函数(比如在c#中)

您不必将getUsers创建为匿名函数。