繁体   English   中英

JavaScript 中的异步函数是什么? JavaScript 中的“异步”和“等待”是什么?

[英]What are asynchronous functions in JavaScript? What is "async" and "await" in JavaScript?

本问答旨在明确回答以下问题:

  • JavaScript 中的异步函数是什么,我们何时以及如何使用它们?
  • JavaScript 中的asyncawait关键字是什么,它们与异步函数有何关系?

要遵循答案,需要以下先决条件:

  • JavaScript的异步编程知识model
  • ES6知识Promise object

介绍

JavaScript 有一个异步 model。 每当异步操作完成时,您通常希望之后执行一些代码。 第一个回调通常用于解决这个问题。 但是,当使用多个异步元素编写代码时,使用回调会出现问题。 因为当您将多个回调相互嵌套时,代码变得难以快速维护。 这种反模式称为回调地狱

承诺

Promises 解决了嵌套回调中出现的许多问题。 Promise 的一个关键属性是它们可以使用promise 链很好地链接在一起。 这允许比回调更简洁的语法和更容易的错误处理。 这是一个例子:

 const randomProm = new Promise((resolve, reject) => { if (Math.random() > 0.5) { resolve('Succes'); } else { reject('Failure'); } }); // Promise chain randomProm.then((value) => { console.log('inside then1'); console.log(value); return value }).then((value) => { console.log('inside then2'); console.log(value); return value }).catch((value) => { console.log('inside catch'); console.log(value); });

异步函数

异步函数建立在 Promise 之上。 它们允许更方便地使用 Promise。 异步函数具有以下属性:

  • async声明/表达式之前的异步将 function 转换为异步 function。 顾名思义 async function 是异步执行的。
  • 异步 function 总是返回 promise 它将任何返回值包装在Promise.resolve(returnval)中。 但是,当在异步 function 中引发未捕获的错误时,它会将返回值包装在Promise.catch(returnval)中。
  • 在异步函数中,您可以使用await关键字,该关键字可以在任何 promise 之前使用。 await使 JS 代码执行停止,直到 promise 解决。 即在异步 function 中的任何进一步代码执行之前,必须满足或拒绝 promise。
  • await要么返回已完成的 promise 的值,要么在拒绝 promise 的情况下抛出错误。 我们可以使用常规的 try-catch 来捕获错误。

让我们用一些例子来澄清这一点:

示例 1:

 const randomProm = new Promise((resolve, reject) => { if (Math.random() > 0.5) { resolve("Succes"); } else { reject("Failure"); } }); // async keyword creates an async function which returns a promise async function ansyncExample() { try { const outcome = await randomProm; console.log(outcome); } catch (error) { console.log(error); } // This return value is wrapped in a promise return 'AsyncReturnVal'; } // ansyncExample() returns a promise, we can call its corresponding then method ansyncExample().then((value) => { console.log(value); }); console.log('I get executed before the async code because this is synchronous');

示例 2:

 // We can use async in function expressions const randomProm = async () => { if (Math.random() > 0.5) { // This value is wrapped in Promise.resolve() return "Succes"; } else { // This value is wrapped in Promise.reject() throw "Failure"; } }; // async keyword creates an async function which returns a promise async function ansyncExample() { // randomProm is async fuction which returns a promise which we can await return await randomProm(); } // ansyncExample() returns a promise, we can call its corresponding then/catch method ansyncExample().then((value) => { console.log("Inside then"); console.log(value); }).catch((value) => { console.log("Inside catch"); console.log(value); }); console.log("I get executed before the async code because this is synchronous");

何时使用异步函数

理论上,每次使用 promise 时,您都可以使用异步 function。 然而,当有多个异步操作返回 Promise 并且相互依赖时,异步函数的威力才真正开始发挥作用。

因为异步 function 允许我们以同步方式编写基于异步 promise 的代码。 代码仍然是异步的,但我们现在可以以同步的方式读取它 它比 promise 链更容易阅读和维护,因此可以更好地扩展(IMO)。

这是一个很好的可读性的例子:

async function ansyncExample() {
    try {
        // 3 async operations which depend on each other
        const firstValue = await firstAsyncFunc();
        const SecondValue = await secondAsyncFunc(firstValue);
        const ThirdValue = await thirdAsyncFunc(SecondValue);
    } catch (error) {
        console.log(error);
    }

    return ThirdValue;
}

的,这对我来说也不清楚。 例如,这是来自https://javascript.info/callbacks的引用

Many functions are provided by JavaScript host environments that allow you to
schedule asynchronous actions. In other words, actions that we initiate now, but
they finish later.

我的意思是有没有我们现在开始的行动,他们之前完成的? 在我看来,单独谈论异步动作是没有意义的。 我们至少需要两行代码。

fst()
snd()

在同步代码中, snd将在fst完成后启动,但在浏览器中,例如,如果fst是一些需要时间的请求,它将阻塞snd 这就是为什么你有 JavaScript 回调,它不会阻止主程序的执行。 那就是fst将在它启动之后而不是在snd之后完成。

暂无
暂无

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

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