文章内容输出来源:拉勾教育 大前端高薪训练营

前言

在JavaScript异步编程【上】和 JavaScript异步编程【中】中,我们已经讲到了处理异步编程的两种方法:回调函数 和 Promise。
那么,我们再来介绍两种ES6中新增的处理异步编程的方法:Generator 和 Async/await 。

Generator

Generator 函数是 ES2015 提供的一种异步编程解决方案,语法行为与传统函数完全不同。

基本介绍

生成器(Generator)函数能生成一组值的序列,但每个值的生成是基于每次请求,并不同于标准函数那样立即生成,每当生成器函数生成了一个值,它都会暂停执行但不会阻塞后续代码执行。

特征与语法

  • 特征

    1,function关键字与函数名之间有一个星号;
    2,函数体内部使用yield表达式,生成一个新的值。

  • 语法

    代码示例如下:

        function * fn () {console.log('1111');yield 100console.log('2222');yield 200console.log('3333');yield 300}const generator = fn()  // 未执行,得到一个生成器对象
    

    function* 这种声明方式(function关键字后跟一个星号)会定义一个生成器函数 (generator function),它返回一个 Generator 对象。

    代码分析

    在上面的代码中,当调用fn函数的时候,会自动返回 Generator 对象,此时使用 generator 进行存储这个对象。然而,生成器函数在执行过程中,一旦遇到yield关键字,函数的执行将会被暂停下来,只有使用 Generator 对象的next()方法,才会让这个函数的函数体开始执行,并且,yield后面的值将会作为 next 的结果返回。

    总的来说就是,Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。

    代码示例如下:

     function* fn () {yield 100yield 200return 300}const generator = fn()  // 未执行,得到一个生成器对象generator.next()  // { value: 100, done: false}generator.next()  // { value: 200, done: false}generator.next()  // { value: 300, done: true}generator.next()  // { value: undefined, done: true}
    

    上面代码一共调用了四次next方法。

    代码分析

    第一次调用,Generator 函数开始执行,直到遇到第一个yield表达式为止。next方法返回一个对象,它的value属性就是当前yield表达式的值100,done属性的值false,表示遍历还没有结束。

    第二次调用,Generator 函数从上次yield表达式停下的地方,一直执行到下一个yield表达式。next方法返回的对象的value属性就是当前yield表达式的值200,done属性的值false,表示遍历还没有结束。

    第三次调用,Generator 函数从上次yield表达式停下的地方,一直执行到return语句(如果没有return语句,就执行到函数结束)。next方法返回的对象的value属性,就是紧跟在return语句后面的表达式的值(如果没有return语句,则value属性的值为undefined),done属性的值true,表示遍历已经结束。

    第四次调用,此时 Generator 函数已经运行完毕,next方法返回对象的value属性为undefined,done属性为true。以后再调用next方法,返回的都是这个值。

  • 总结

    Generator 函数执行过程中,遇到yield关键字,函数的执行将会被暂停下来,只有调用Generator 对象的next()方法,才会让这个函数继续执行,并且yield后面的值将会以对象的形式进行返回,返回的对象中包含两个属性:一是value,当前的返回的值;二是done,它是一个布尔值,表示是否遍历结束。

yield 与 return

通过上面的描述,可以知道 yield 与 return 一样都可以返回值,那么,他们有何相同点和不同点呢?

  • 相同点

    都能返回紧跟在语句后面的那个表达式的值。

  • 不同点

    1,每次遇到yield,函数暂停执行,下一次再从该位置继续向后执行,而return语句不具备位置记忆的功能。
    2,一个函数里,只能执行一次(或者说一个)return语句,但是可以执行多次(或者说多个)yield表达式。
    3,正常函数只能返回一个值,因为只能执行一次return;Generator 函数可以返回一系列的值,因为可以有任意多个yield。

Async/await

async/await 是ES2017提供的处理异步函数的方式,它其实是 Generator 函数的语法糖。

  • 语法

    代码示例如下:

    const fn = async function () {await 100await 200return 300
    }
    

可以看到,async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await。

async函数对 Generator 函数的改进,体现在以下四点。

  • 1,内置执行器。

    Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器。也就是说,async函数的执行,与普通函数一模一样,只要一行。

    fn();
    

    上面的代码调用了fn函数,然后它就会自动执行,输出最后结果。这完全不像 Generator 函数,需要调用next方法,或者用co模块,才能真正执行,得到最后结果。

  • 2,更好的语义。

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

  • 3,更广的适用性。

    co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)。

  • 4,返回值是 Promise。

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

总结

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

JavaScript异步编程【下】 -- Generator、Async/await相关推荐

  1. JS 异步编程终极解决方案 async/await 的使用手册

    前言 async functions 和 await 关键字是最近添加到JavaScript语言里面的.它们是ECMAScript 2017 JavaScript版的一部分.简单来说,它们是基于pro ...

  2. JavaScript 异步编程--Generator函数、async、await

    JavaScript 异步编程–Generator函数 Generator(生成器)是ES6标准引入的新的数据类型,其最大的特点就是可以交出函数的执行的控制权,即:通过yield关键字标明需要暂停的语 ...

  3. @async 没有异步_玩转javascript异步编程

    一般知道,js脚步语言的执行环境是单线程的,就是它会等一个任务完成,才会进行第二个任务,然后一直向下进行,这样的执行环境简单,但是处理不了复杂的运用,当一个请求需要非常旧的时间的时候,下一个流程就会被 ...

  4. 【学习笔记】Part1·JavaScript·深度剖析-函数式编程与 JS 异步编程、手写 Promise(二、JavaScript 异步编程)

    [学习笔记]Part1·JavaScript·深度剖析-函数式编程与 JS 异步编程.手写 Promise(课前准备) [学习笔记]Part1·JavaScript·深度剖析-函数式编程与 JS 异步 ...

  5. 写给初学者的JavaScript异步编程和背后思想

    导读: 对于接触JavaScript这门编程语言没有多久的本菜鸡而言,在相当长的一段时间内,我都完全无法理解这门语言中的异步编程,不明白什么叫异步编程以及为什么需要异步编程.为什么顺序执行程序就不行了 ...

  6. 网页javascript加载不出_写给初学者的JavaScript异步编程和背后思想

    导读:对于接触JavaScript这门编程语言没有多久的本菜鸡而言,在相当长的一段时间内,我都完全无法理解这门语言中的异步编程,不明白什么叫异步编程以及为什么需要异步编程.为什么顺序执行程序就不行了呢 ...

  7. JavaScript异步编程原理

    众所周知,JavaScript 的执行环境是单线程的,所谓的单线程就是一次只能完成一个任务,其任务的调度方式就是排队,这就和火车站洗手间门口的等待一样,前面的那个人没有搞定,你就只能站在后面排队等着. ...

  8. Javascript异步编程之一异步原理

    本系列的例子主要针对node.js环境,但浏览器端的原理应该也是类似的. 本人也是Javascript新手,把自己这段时间学习积累的要点总结下来,希望可以对同样在学习Javascript/node.j ...

  9. JavaScript异步编程

    JavaScript异步编程 一.概述 1.单线程模型 2.同步任务和异步任务 3.任务队列和事件循环 4.异步操作的模式 回调函数 事件监听 发布/订阅 5.异步操作的流程控制 串行执行 并行执行 ...

最新文章

  1. 浅谈算法和数据结构: 五 优先级队列与堆排序
  2. cli/c++与C#比较之我见
  3. 【bzoj1369】[Baltic2003]Gem(树形dp+结论)
  4. 项目奖金一般有多少_全年一次性奖金如何进行纳税筹划?
  5. Hbase 2.x Region in transition (永久RIT) 异常解决
  6. think php上传图片,上传 · ThinkPHP5.0完全开发手册 · 看云
  7. 服务器的原理,服务器原理
  8. 基于Matlab人脸识别(PCA算法)
  9. 确定空间直线延长线上的一点
  10. 服务器外链图片不显示,nginx服务器设置图片防盗链,禁止图片外链
  11. 独立站SEO到底怎么做?
  12. 《安富莱嵌入式周报》第245期:2021.12.20--2021.12.26
  13. 国务院智囊建议全面放开二胎:越晚越被动
  14. android studio中的模拟器,使用Android Studio创建Andorid模拟器
  15. 第二篇 在Arduino IED环境下测试ESP8266模块与外网通信
  16. 第三届世界5G大会召开之前,我们来复习一下这本6G白皮书
  17. Gson项目使用全解析
  18. 当人工智能变成美妆博主……
  19. LoCCS专访:后量子密码技术让Hcash走得更远
  20. 猫,量子力学,和手机人像摄影之变

热门文章

  1. 多重异常处理 java
  2. javascript 西瓜一期 01.什么是编程 什么是编程语言
  3. django-cookie与session的应用场景
  4. mysql执行计划字段解释
  5. 莫比乌斯反演部分题目总结
  6. our happy ending(状压dp)
  7. PostgreSQL 范围过滤 + 其他字段排序OFFSET LIMIT(多字段区间过滤)的优化与加速
  8. SolidEdge 如何绘制局部视图 局部放大图
  9. c语言 谭浩强 一维数组内放10个学生成绩 全局变量写一个函数 最高分、最低分、平均分...
  10. 分享个 之前写好的 android 文件流缓存类,专门处理 ArrayList、bean。