简体   繁体   English

了解 NodeJS 上的异步/等待

[英]Understanding async/await on NodeJS

I think my understanding of it might be affected by my experience with .NET 's async/await , so I'd like some code example:我认为我对它的理解可能会受到我对.NETasync/await经验的影响,所以我想要一些代码示例:

I'm trying to make a express controller wait 5 seconds before returning the response:我试图让一个快速控制器在返回响应之前等待 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 code doesn't work, the browser keeps loading and loading and never shows a thing.此代码不起作用,浏览器不断加载和加载并且从不显示任何内容。

The getUser function I built based on this SO answer , and the controller method, based on my (mistaken) understanding of how it works so I'd like some clarification and correction:我基于这个 SO answer构建的getUser函数和控制器方法,基于我对它如何工作的(错误的)理解,所以我想要一些澄清和更正:

1. when should I use await ? 1. 我什么时候应该使用await

To my understanding, you should use await before an async function call.据我了解,您应该在async函数调用之前使用await Is this correct?这是正确的吗? Also, why can I call await before a non-async function that returns a promise?另外,为什么我可以在返回承诺的非异步函数之前调用 await ?

2. When should I use async ? 2. 我什么时候应该使用async

To my understanding, you mark a function as an async one so that it can be called with the await keyword.据我了解,您将一个函数标记为async函数,以便可以使用await关键字调用它。 Is this correct?这是正确的吗? Also, [why] do I have to wrap my await getUsers(5000) call in an anonymous async function?另外,[为什么] 我必须将我的await getUsers(5000)调用包装在匿名异步函数中?

To clear a few doubts -澄清几个疑惑——

  1. You can use await with any function which returns a promise.您可以将await与任何返回承诺的函数一起使用。 The function you're awaiting doesn't need to be async necessarily.您正在等待的功能不一定是async
  2. You should use async functions when you want to use the await keyword inside that function.当您想在该函数中使用await关键字时,您应该使用async函数。 If you're not gonna be using the await keyword inside a function then you don't need to make that function async .如果您不打算在函数中使用await关键字,那么您不需要将该函数设为async
  3. async functions by default return a promise. async函数默认返回一个承诺。 That is the reason that you're able to await async functions.这就是您能够await async函数的原因。

From MDN -来自MDN -

When an async function is called, it returns a Promise.当异步函数被调用时,它返回一个 Promise。

As far as your code is concerned, it could be written like this -就您的代码而言,它可以这样编写-

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',
      },
    ]);
};

You can await any promise in an async function.您可以在async函数中await任何承诺。 The code after the await will be executed after the promise that you are awaiting finished. await之后的代码将在您等待的承诺完成后执行。

This is a great alternative to classic JavaScript callbacks.这是经典 JavaScript 回调的绝佳替代方案。

I wrote a blog about it -> https://github.com/Gameye/js-async I hope this will help you!我写了一篇关于它的博客 -> https://github.com/Gameye/js-async希望这对你有所帮助!

Async functions in Javascript Javascript 中的异步函数

The async keyword turns a regular JS function declaration into an asynchronous function declaration: async关键字将常规 JS 函数声明转换为异步函数声明:

function syncFunc {// dostuff}
async function asyncFunc {// dostuff} // the async keyword is placed before the function keyword

An async function returns a Promise:异步函数返回一个 Promise:

  • When the async function returns a value, the Promise will be resolved with the returned value.当 async 函数返回一个值时,Promise 将使用返回值进行解析。
  • When the async function throws an exception or some value, the Promise will be rejected with the thrown value.当 async 函数抛出异常或某个值时,Promise 将被抛出的值拒绝。

Inside an async function you can use the await keyword.在异步函数中,您可以使用await关键字。 await placed before a promise causes the async function to pause until the promise is settled (either rejected or fulfilled) await放置在承诺之前会导致异步函数暂停,直到承诺完成(被拒绝或完成)

  • . . When the promise fullfills The value of the await expression is the value of the fullfilled promise.当promise fullfills 时, await表达式的值就是fullfill 的promise 的值。
  • When the promise is rejected the await expression throws the rejected value.当承诺被拒绝时, await表达式会抛出被拒绝的值。

Example:示例:

 function makePromise(x) { return new Promise(resolve => { setTimeout(() => { resolve(x); }, 1000); }); } async function asyncFunc() { var x = await makePromise(1); // the function is paused here until the promise is fulfilled console.log(x); // logs 1 return x; } const returnedProm = asyncFunc(); // the async func returns a promise returnedProm.then((x) => console.log(x)); // This promise is fulfilled with the return value from the async func, so this logs 1

When to use asynchronous functions:何时使用异步函数:

Async functions are a useful tool when you have multiple asynchronous actions (implemented as promises) which depend on each other.当您有多个相互依赖的异步操作(作为承诺实现)时,异步函数是一个有用的工具。 For example when your second promise needs data that your first promise will provide.例如,当您的第二个承诺需要您的第一个承诺将提供的数据时。 You now can conveniently use the await keyword to first receive the data in promise 1, and then pass this data as an argument to promise 2.您现在可以方便地使用await关键字首先接收 promise 1 中的数据,然后将此数据作为参数传递给 promise 2。

In other words, async function can via the await keyword make asynchronous programming behave like synchronous programming.换句话说,异步函数可以通过await关键字使异步编程表现得像同步编程。 As a consequence your applications are easier to understand.因此,您的应用程序更易于理解。

async await are just syntactic sugar for promises. async await 只是 promise 的语法糖。

you use them like you use promises when you want your code to run on complete of a function.当您希望代码在一个函数完成时运行时,您可以像使用 promise 一样使用它们。

async function asyncOperation(callback) {
    const response = await asyncStep1();
    return await asyncStep2(response);
}

is the exact thing if you used promises land syntax:如果您使用 promises land 语法,那就是确切的事情:

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

The new async/await syntax allows you to still use Promises, but it eliminates the need for providing a callback to the chained then() methods.新的 async/await 语法允许您仍然使用 Promises,但它消除了为链接的 then() 方法提供回调的需要。

The callback is instead returned directly from the asynchronous function, just as if it were a synchronous blocking function.回调直接从异步函数返回,就好像它是一个同步阻塞函数。

let value = await myPromisifiedFunction(); 

When you are planning to use await in your function you should mark your function with async keyword (like in c#)当您计划在您的函数中使用 await 时,您应该使用 async 关键字标记您的函数(如在 c# 中)

You don't have to create your getUsers as anonymous function.您不必将 getUsers 创建为匿名函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM