资讯专栏INFORMATION COLUMN

JavaScript的async 的学习

Leo_chen / 1023人阅读

摘要:函数内部语句返回的值,会成为方法回调函数的参数。也就是说,只有函数内部的异步操作执行完,才会执行方法指定的回调函数。命令后面的对象如果变为状态,则的参数会被方法的回调函数接收到。

async 函数

ES2017 标准引入了 async 函数,使得异步操作变得更加方便,就是 Generator 函数的语法糖。
对比一下:

const fs = require("fs");

const readFile = function (fileName) {
  return new Promise(function (resolve, reject) {
    fs.readFile(fileName, function(error, data) {
      if (error) return reject(error);
      resolve(data);
    });
  });
};

const gen = function* () {
  const f1 = yield readFile("/etc/fstab");
  const f2 = yield readFile("/etc/shells");
  console.log(f1.toString());
  console.log(f2.toString());
};

async的书写

const asyncReadFile = async function () {
  const f1 = await readFile("/etc/fstab");
  const f2 = await readFile("/etc/shells");
  console.log(f1.toString());
  console.log(f2.toString());
};

async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已。

async的优点

async的书写方式,比之前的promise、genenator方式都好,以下四点优势:

内置执行器。
async函数的执行,与普通函数一模一样,只要一行。function(),这样就可以执行,不像 Generator 函数,需要调用next方法,或者用co模块,才能真正执行,得到最后结果。

更好的语义
async和await,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。

更广的适用性
yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。

返回值是 Promise
async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。

进一步说,async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖。

返回值

async函数返回一个 Promise 对象。async函数内部return语句返回的值,会成为then方法回调函数的参数。

async function f() {
  return "hello world";
}

f().then(v => console.log(v))
// "hello world"

上面代码中,函数f内部return命令返回的值,会被then方法回调函数接收到。async函数内部抛出错误,会导致返回的 Promise 对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到。

async函数返回的 Promise 对象,必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。

await

正常情况下,await命令后面是一个 Promise 对象。如果不是,会被转成一个立即resolve的 Promise 对象。上面代码中,await命令的参数是数值123,它被转成 Promise 对象,并立即resolve。

await命令后面的 Promise 对象如果变为reject状态,则reject的参数会被catch方法的回调函数接收到。

async function f() {
  await Promise.reject("出错了");
}

f()
.then(v => console.log(v))
.catch(e => console.log(e))
// 出错了

只要一个await语句后面的 Promise 变为reject,那么整个async函数都会中断执行。

以上都是学习过程的笔记。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/89078.html

相关文章

  • JavaScript基础——深入学习async/await

    摘要:等待的基本语法该关键字的的意思就是让编译器等待并返回结果。这里并不会占用资源,因为引擎可以同时执行其他任务其他脚本或处理事件。接下来,我们写一个火箭发射场景的小例子不是真的发射火箭 本文由云+社区发表 本篇文章,小编将和大家一起学习异步编程的未来——async/await,它会打破你对上篇文章Promise的认知,竟然异步代码还能这么写! 但是别太得意,你需要深入理解Promise后,...

    张金宝 评论0 收藏0
  • ES6-7

    摘要:的翻译文档由的维护很多人说,阮老师已经有一本关于的书了入门,觉得看看这本书就足够了。前端的异步解决方案之和异步编程模式在前端开发过程中,显得越来越重要。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。 JavaScript Promise 迷你书(中文版) 超详细介绍promise的gitbook,看完再不会promise...... 本书的目的是以目前还在制定中的ECMASc...

    mudiyouyou 评论0 收藏0
  • 学习JavaScript循环下async/await

    摘要:原因是的循环方法等是并行迭代,可以理解为的效果是无效的解决方案使用最原始的循环将上述的模拟异步任务修改为或参考连接用来处理异步在不起作用解决异步循环的使用方法 问题描述 在进行业务开发的过程中,使用了数组的高级函数map,同时使用了ES6语法async/await,发现在map循环下任务是异步执行的,并不符合预期 例子说明 /** * 异步打印数据 */ const echo =...

    Ilikewhite 评论0 收藏0
  • 重学前端学习笔记(十七)--Promise里代码为什么比setTimeout先执行?

    摘要:版本以及之前,本身还没有异步执行代码的能力,宿主环境传递给引擎,然后按顺序执行,由宿主发起任务。采纳引擎术语,把宿主发起的任务称为宏观任务,把引擎发起的任务称为微观任务。基本用法示例的回调是一个异步的执行过程。 笔记说明 重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完整的...

    pinecone 评论0 收藏0
  • 重学前端学习笔记(十七)--Promise里代码为什么比setTimeout先执行?

    摘要:版本以及之前,本身还没有异步执行代码的能力,宿主环境传递给引擎,然后按顺序执行,由宿主发起任务。采纳引擎术语,把宿主发起的任务称为宏观任务,把引擎发起的任务称为微观任务。基本用法示例的回调是一个异步的执行过程。 笔记说明 重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完整的...

    zorpan 评论0 收藏0

发表评论

0条评论

Leo_chen

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<