在学习 async/await 语法之前,您需要很好地了解 JavaScript promises。
async/await 的工作原理
async/await 语法是一种特殊语法,用于帮助您处理 promise 对象。它使您的代码更简洁、更清晰。
处理 时,需要将调用链接到返回 using 方法的函数或变量。PromisePromisethen/catch
当你有很多承诺时,你还需要很多方法链。例如,以下是使用该函数检索数据的方法:thenfetch()
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log(error));
典型的 Fetch API 实现
在上面的代码中,该函数返回一个 ,我们使用该方法处理它。在第一种方法中,我们接受 from 请求并使用该方法将其转换为对象。fetch()Promisethen()then()responsejson()
在第二种方法中,我们从对方法的调用中接收返回的数据,然后将该数据记录到控制台。then()jsonjson()
我们还添加了该方法来处理运行请求时可能发生的任何错误。catch()
代码真的不难理解,但是我们可以通过删除 and 链来使其更漂亮,这也删除了回调函数。.then().catch()
Await 关键字
该关键字基本上使 JavaScript 等待对象被解析或拒绝。您不必在方法中使用回调模式,而是可以将已实现的承诺分配给如下所示的变量:awaitPromisethen()
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');const json = await response.json();console.log(json)
使用 Await 代替 .then() 方法链接
关键字放在调用返回 promise 的函数或变量之前。它使 JavaScript 等待 promise 对象安定,然后再运行下一行中的代码。await
现在,如果运行上面的代码,可能会收到如下错误:
SyntaxError: await is only valid in async functions and the top level bodies of modules
在异步函数之外使用 Await 时出现语法错误
发生此错误的原因是必须在异步函数或模块中使用关键字。await
Async 关键字
若要创建异步函数,需要在函数名称前添加关键字。请看下面示例中的第 1 行:async
async function runProcess() {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const json = await response.json();
console.log(json)}runProcess();
创建异步函数
在这里,我们创建了一个名为的异步函数,并将使用该关键字的代码放入其中。然后,我们可以通过调用它来运行异步函数,就像常规函数一样。runProcess()await
如何处理 Async/Await 中的错误
要处理 async/await 语法中可能发生的错误,可以使用 try/catch 块来捕获来自 promise 的任何拒绝。
请参阅以下示例:
async function runProcess() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const json = await response.json();
console.log(json);
} catch (error) {
console.log(error);
}}runProcess();
在异步函数中添加 try/catch
放在函数内部的 try/catch 块将处理来自 promise 对象的拒绝。runProcess()
现在,我们有了之前创建的标准 Promise 代码的完整 async/await 版本。以下是两者之间的比较:
PROMISE---异步Promise 与 Async/Await 代码比较
在 async/await 版本中,promise 的结果直接分配给变量。在标准 promise 版本中,promise 的结果作为参数传递给方法。.then()
大多数开发人员更喜欢 async/await 版本,因为它看起来更简单。
如何在 IIFE 和箭头函数中使用 Async/Await
立即调用函数表达式 (IIFE) 是一种用于在定义函数后立即执行函数的技术。
与常规函数和变量不同,IIFE 在执行后将从正在运行的进程中删除。
除了标准函数之外,您还可以制作异步 IIFE。当您只需要运行一次异步函数时,这很有用:
(async function () {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const json = await response.json();
console.log(json);
} catch (error) {
console.log(error);
}})();
IIFE 异步函数示例
您还可以在创建异步函数时使用箭头语法,如下所示:
const runProcess = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const json = await response.json();
console.log(json);
} catch (error) {
console.log(error);
}};runProcess();
Arrow 异步函数示例
您可以在代码中随意使用所需的语法。
为什么使用 async/await 语法?
async/await 语法使您能够在不使用 and 方法链接的情况下处理 promise,这也消除了对嵌套回调的需求。.then().catch()
当您在确定承诺后有一个复杂的流程时,这种好处是显着的。
回到上面的示例,假设方法中有一个条件语句,如下所示:.then()
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => {
if (json.userId == 1) {
json.completed == false;
} else {
json.completed == true;
}
})
.catch(error => console.log(error));
Promise 方法中的 if/else 块then()
在这里,您可以看到接受数据的回调函数内部有一个 if/else 块。json
与 async/await 版本相比,此代码很难推理和修改,如下所示:
(async function () {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const json = await response.json();
if (json.userId == 1) {
json.completed == false;
} else {
json.completed == true;
}
console.log(json);
} catch (error) {
console.log(error);
}})();
通过使用 async/await 语法,可以减少对方法链接和嵌套回调的需求。这会影响代码的可读性,尤其是当您有嵌套代码(如 if/else 和 for 循环块)时。
结论
现在,您已经了解了 async/await 语法的工作原理。该语法通过消除对 和 方法链接的需求,使使用 promise 变得更加容易,这也消除了对嵌套回调的需求。.then().catch()
即使关键字只能在函数内部使用,也可以使用 IIFE 仅调用异步函数一次。awaitasync