JS中的异步函数是什么?什么是async and await关键字?

问题描述 投票:0回答:1

此问答旨在为以下问题提供清晰的答案:

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

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

  • JS异步编程模型的知识
  • ES6 Promise对象的知识
javascript asynchronous promise async-await es6-promise
1个回答
0
投票

简介

JavaScript具有异步模型。每当异步动作完成时,您通常都希望随后执行一些代码。第一个回调是通常用来解决这个问题。但是,当使用多个异步元素编程代码时,使用回调会出现问题。因为当您在彼此之间嵌套多个回调时,代码变得很难快速维护。此反模式称为callback hell

承诺

承诺解决了嵌套回调中出现的许多问题。许诺的关键特性是可以使用promise chain将它们很好地链接在一起。这样可以使语法比回调更简洁,并且更易于处理错误。这是一个例子:

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);
});

异步功能

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

    在函数声明/表达式之前使用
  • async关键字将函数转换为异步函数。顾名思义,异步函数是异步执行的。
  • 一个异步函数总是返回一个promise。它将所有返回的值包装在Promise.resolve(returnval)中。但是,当在异步函数中引发未捕获的错误时,它将返回值包装在Promise.catch(returnval)中。
  • 在异步函数内部,您可以使用await关键字,该关键字可以在任何承诺之前使用。 await使JS代码执行停止,直到兑现承诺为止。也就是说,在执行异步函数内的任何其他代码之前,必须兑现或拒绝承诺。
  • await要么返回已实现承诺的值,要么在被拒绝承诺的情况下引发错误。我们可以使用常规的try-catch来捕获错误。

让我们用一些例子来阐明这一点:

示例1:

const randomProm = new Promise((resolve, reject) => {
    if (Math.random() > 0.5) {
        resolve("Succes");
    } else {
        reject("Failure");
    }
});

// async keyword creates 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 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");

何时使用异步功能

理论上,您每次使用诺言时都可以使用异步功能。但是,当有多个异步操作返回承诺并相互依赖时,异步功能的功能真正开始发挥作用。

因为异步功能允许我们以同步方式编写基于异步诺言的代码。 代码仍然是异步的,但是我们现在可以以同步方式读取它。它比允诺链更易于阅读和维护,因此扩展性更好(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;
}
© www.soinside.com 2019 - 2024. All rights reserved.