修身养性,知行合一

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

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

2020年12月17日 1799点热度 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
    • 捕获异常
最新 热点 随机
最新 热点 随机
关于 *.vue 文件中使用 TypeScript 声明类型报错的解决方案 element table 加载时宽度闪烁问题 windows 无法登录便签、OneNote等应用 vue2 中 vuex 对 ts 的支持 封装一个极简的右键菜单 vue2 使用 @vue/composition-api 的一些问题
使用 windows 命令启动某个程序 js的装饰符 @ TypeError: ObjectId('') is not JSON serializable Vue移动项目切换页面时不同动画的实现小技巧 IIS Express 通过IP访问的方法和坑 Windows server 2012 IIS 安装 core 2.2后直接503的解决方案

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

COPYRIGHT © 2021 jeremyjone.com. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

京ICP备19012859号-1

京公网安备 11010802028585号