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

2023-12-25

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

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

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

  • 了解 JavaScript 的异步编程模型
  • ES6 Promise 对象的知识

Intro

JavaScript 有一个异步模型。每当异步操作完成时,您通常希望随后执行一些代码。第一个回调是 经常用来解决这个问题。然而,当使用多个异步元素编写代码时,使用回调会出现问题。因为当您将多个回调嵌套在一起时,代码变得很难快速维护。这种反模式称为回调地狱.

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在函数声明/表达式将函数转换为异步函数之前。顾名思义,异步函数是异步执行的。
  • 异步函数总是返回一个承诺。它将任何返回值包装在Promise.resolve(returnval)。但是,当异步函数内部抛出未捕获的错误时,它将返回值包装在Promise.catch(returnval).
  • 在异步函数中,您可以使用await可以在任何 Promise 之前使用的关键字。await使 JS 代码执行停止,直到 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 时都可以使用异步函数。然而,当存在多个返回 Promise 且相互依赖的异步操作时,异步函数的威力才真正开始发挥作用。

因为 async 函数允许我们以同步方式编写基于异步 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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐