likes
comments
collection
share

Promise 系列 | 番外篇 - async/await 才是真香

作者站长头像
站长
· 阅读数 10

前言

前面的几篇文章我们全面学习了 Promise 的相关知识,不过在我们实际开发中使用 async/await 的情况也是很多的,而且比较重要。

async/await 香在哪里呢 ?在处理异步代码时,和 Promise 又有什么差别呢 ?

async

async 用于声明一个异步函数,async 函数是 AsyncFunction 构造函数的实例

定义一个 async 异步函数,可以使用这三种方法:

async function foo() {}

const foo = async () => {}

class Example {
  async foo() {}
}

这和普通的函数有什么区别呢 ? 答:基本上没有区别。我们看一下 👇

Promise 系列 |  番外篇 - async/await 才是真香

讲道理,你作为一个异步函数不应该让同步代码先行吗,怎么自己还插队呢

因为它目前还不是一个完全的异步函数,而且异步执行的作用域也不对,具体的内容会在后面讲到

但我们会发现这个 foo() 函数竟然是一个 Promise

Promise 系列 |  番外篇 - async/await 才是真香

前面已经学了 Promise 了,不知道这个 “Promise” 是不是正经 Promise 呢

调一个 then 方法试试能不能接收到 foo() 的值:

async function foo() {
  console.log(1);
  console.log(2);
}
foo().then(res => {
  console.log(res);  // undefined
})

我们发现用 async 定义的函数 foo()真的可以调用 then() 方法

res 的值是 undefined 的根本原因是 foo() 函数没有返回值,假定一个返回值重写

async function foo() {
  // ...
  return 200
}
foo().then(res => {
  console.log(res);  // 200
})

学习过前几篇文章的小伙伴们,这里你可以尝试将返回值定义为一个 thenable 对象、promise 尝试会有什么结果 ?这篇文章不再专门对此举例

Promise 系列 |  番外篇 - async/await 才是真香

是不是感觉这两个 foo 很像,再来试一下异常处理:

async function foo() {
  // ...
  throw new Error("error message")
}
foo().catch(err => {
  console.log(err);  // error message
})

我们发现真的可以,foo() 是一个 Promise。可是这有什么用,我们已经有定义 Promise 的方法了。别着急,我们还有一个伙伴没有介绍呢

await

await 关键字只在 async 函数内有效。在 async 函数体之外使用它,会抛出语法错误 SyntaxError 

也就是说 await 必须要在 async 里面,像这样:

async function foo() {
  await ...
}

那么 await 具体怎么使用呢 ?来看一下这段代码

Promise 系列 |  番外篇 - async/await 才是真香

我们发现在这段代码中打印 code,并不会像之前的 Promise 一样返回 undefined 了,而是直接给到我们想要的结果。是不是比之前舒服了很多?!不用操心代码执行顺序的问题,全部同步化。

await 下面的内容就相当于在 promsie 的 then() 方法中一样,会在拿到结果后继续执行

🐝 可以在 await 后继续发起“链式调用”,而且作为 foo() 的异步函数也不会影响后续代码的执行:

Promise 系列 |  番外篇 - async/await 才是真香

对了,还有一点。在 Promsie 被拒绝或抛出异常时,可直接使用 try/catch 捕获错误原因

function resolveAfter2Seconds(code) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(code);
    }, 2000);
  });
}

async function foo() {
  try {
    await resolveAfter2Seconds(500);
  } catch (err) {
    console.log(err);  // 500
  }
}

foo();

结语

相对于 Promise,async/await 在处理一般异步代码时确实会更加的直观和简洁,尤其是在处理链式调用时表现的更加优秀。

十分感谢小伙伴们能看到这里,这篇文章相对于前几篇篇幅略小,但不得不承认 async/await 确实很香,所以理解这篇文章很容易,我们更应该在实际开发中多实践才行。

转载自:https://juejin.cn/post/7248648979042730043
评论
请登录