修身养性,知行合一

  • 首页
  • 爱码
    • 系统
    • 数据库
    • JavaScript
    • CSharp
    • Python
  • 生活
    • 文化
    • 美食
  • 杂谈
  • 关于
修身养性,知行合一
码字,杂谈
  1. 首页
  2. 爱码
  3. 前端
  4. JavaScript
  5. 正文

真丶深入理解JavaScript异步编程(三):async / await

2020年12月17日 3681点热度 0人点赞 0条评论

这一篇内容比较短,介绍新增的语法糖。其实也不算新了。。。

async / await

这两个写法是 ES6 新加的特性,这让我们的代码更加简单明了。但是这并不是什么新技术,只是一个语法糖而已,它的本质还是 Promise。

await

我个人理解,await 是这两个语法糖的重点。它具有以下特点:

  • 它后面需要跟一个 Promise,如果是一个值,则会自动包裹成一个 Promise
  • 它需要在异步函数内部使用,也就是函数必须使用 async 修饰。

await 相当于前面提到过的 then,使用 await 等待其后 Promise 的结果,只有获取了结果,程序才会继续执行,否则会一直等待。

async function get() {
  let name = await new Promise(resolve => {
    setTimeout(() => resolve("jeremyjone"), 1000);
  });
  console.log(name);
}

get(); // 等待1秒后,打印:jeremyjone

async

先来看一下 async 的写法:

async function get() {
  return "jeremyjone";
}

此时 get 方法摇身一变,成了一个异步函数,它本质上返回一个 Promise,我们在使用的时候仍然可以通过 then 来使用。这也就是为什么 await 需要在 async 修饰的函数中,它们相互又可以成为一个链式操作:

// 接上例
get().then(v => console.log(v)); // jeremyjone

// 或者使用 await
let r = await get();
console.log(r); // jeremyjone

此时的 get 方法就相当于:

function get() {
  return new Promise(resolve => {
    resolve("jeremyjone");
  });
}

这就是两个异步语法糖的用法。

捕获异常

捕获 async 的异常

因为 async 方法返回的是一个 Promise,所以和普通 Promise 的异常捕获一样,在调用时通过 .catch() 即可捕获。

async function get() {
  return "jeremyjone";
}

// 调用
get()
  .then(v => console.log(v))
  .catch(err => console.log(err));

这是不存在任何问题的。

捕获 await 的异常

最简单的方式,我们可以通过 try...catch 直接捕获 await 语句的异常:

async function get() {
  try {
    let name = await new Promise(resolve => {
      setTimeout(() => resolve("jeremyjone"), 1000);
    });
    console.log(name);
  } catch (error) {
    console.log(error);
  }
}

但是这样不够优雅,结合我之前写过的内容,可以使用大神封装好的库。但是我又不想安装,所以直接自己封装成函数。

它的思路是这样的:写一个方法,包装所有的 Promise,让所有 Promise 同时返回成功的数据和异常的错误,然后由使用者抉择如何使用它们。如果成功,那么异常为 null;如果失败,那么数据则为 undefined。

不得不说,大神的思路简单清晰,而且代码非常简单,易于理解。

PS:有时候我们与大神差的真的只是思路。[偷笑]

function to(promise, errExt) {
  return promise
    .then(data => [null, data])
    .catch(err => {
      if (errExt) {
        Object.assign(err, errExt);
      }
      return [err, undefined];
    });
}

多么的清晰。将这个函数包装到所有需要使用的 Promise,现在 await 返回的将是一个具有两个参数的数组,第一个值是异常,第二个值是数据,随便使用。

async function get() {
  const [err, name] = await to(
    new Promise(resolve => {
      setTimeout(() => resolve("jeremyjone"), 1000);
    })
  );
  console.log(name);
}

是不是优雅了很多~~~

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: JavaScript 异步
最后更新:2020年12月17日

jeremyjone

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

文章评论

取消回复

文章目录
  • async / await
    • await
    • async
    • 捕获异常
最新 热点 随机
最新 热点 随机
推一个vscode纯黑主题 vue 的递归插槽穿透 Github Pages SPA 重定向 行间距引出的 DOCTYPE 怪异行为 写个小彩蛋 绘制一个可重用的线条阴影
如何突破.NET Core 2.2的上传大小限制 初一随笔 2021就要过去了 行间距引出的 DOCTYPE 怪异行为 .net core 中使用 websocket vue2 使用 @vue/composition-api 的一些问题

(っ•̀ω•́)っ✎⁾⁾ 开心每一天

COPYRIGHT © 2021 jeremyjone.com. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

京ICP备19012859号-1

京公网安备 11010802028585号