2019独角兽企业重金招聘Python工程师标准>>>

ES6 Generator 初体验

听说 ES6 的 Generator 是一个很神奇的函数,所以去了解了一下。 因为它不同于以往的寻常函数,但是带来的体验却非常好 。这里首先讲了 Generator 是什么,分割线后面用了一个例子来说明 Generator 到底好在哪里 ~ (可以选择性阅读~ )

Generator 是一种异步编程解决方案,不明白?往下看 ~

Generator 到底是什么?官方文档是这样说的:“Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.”

意思就是 Generator 函数内部的执行是可以暂停的。你能够执行到一半退出函数,同时执行到当前的上下文环境(包括变量等等)全部被保存下来,如果我们稍后又进来继续执行下一段,此时是在上次状态的基础上继续往下执行。感觉和别的函数很不一样,如何去理解呢?

直接上代码:

var myGen = function*(){  // 定义一个 Generator 函数var one = yield 1; var two = yield 2;var three = yield 3;console.log(one,two,three);
}
var gen = myGen();
console.log(gen.next());  //第一次执行函数,输出 {value:1,done:false}
console.log(gen.next());  //第二次执行函数,输出 {value:2,done:false}
console.log(gen.next()); //第三次执行函数,输出 {value:3,done:false}
console.log(gen.next());  //第四次执行函数,输出{value:undefined,done:true}

可以看到 function 后面加了一个 * 号,那是特有的 Generator 的写法,function* 就表示我定义了一个 Generator function。内部还有三个 yield 。

那么上面那段函数是如何执行的呢,一步一步来:

  1. 定义一个 Generator 函数 —— var myGen = function*(){…} ;

  2. var gen = myGen() 进行赋值,接下来想要执行函数需要调用 next(),因为 Generator 函数不会自己执行,next() 可以 return 一个对象,包含两个属性,一个是输出的值(yielded value),还有一个是 done property,表示这个 Generator 函数是否已经输出了最后一个值(yielded its last value)了;

  3. 调用 next() 后,执行函数内部第一条语句 var one = yield 1,由于这条函数执行顺序是自右向左,所以先执行 yield 1,yield 1 这里的作用类似 return 1,返回一个 1 ,同时暂停了函数的执行,它后面的语句并不会继续执行下去。所以第一句 console.log(gen.next()) 输出 1。

  4. 以此类推,最后的 console.log(gen.next()) 结果为 {value:undefined,done:true},因为函数已经没有任何 yield,没有 return 任何值回来,done 为 true 表示这个 Generator 函数执行结束了。

  5. myGen 函数内的 console.log(one,two,three) 会输出什么呢? 1,2,3 ?猜错了!其实这里输出的是 undefined,undefined,undefined。因为 yield 在 var one = 和 1 中间,所以 1 并没有赋值到变量 one 上面。

    下面加一点好玩的东西:把上面所有的 console.log() 改成下面这个样子。

    
    console.log(gen.next());
    console.log(gen.next(4));
    console.log(gen.next(5));
    console.log(gen.next('a'));

    这时, console.log(one,two,three) 输出的就是 4,5,a。

    WHY?? 刚刚说到 var one = yield 1;的执行顺序是自右向左的,执行到 yield 1就暂停了,所以并没有给 one 赋值,所以执行 console.log(gen.next(4)) 语句的时候,把参数 4 赋值给了 one ,然后继续执行 yield 2,以此类推...

然而这看起来好像并没有什么卵用?别急,继续往下看 ~

———————————我是分割线—————————————

首先我们知道平常经常会遇到这样一种情况,就是需要写嵌套的 AJAX,特别是比较复杂的项目里面,AJAX 一层层嵌套( 会存在多层回调嵌套,叫做 Pyramid of Doom),体验非常糟糕。

比如下面这样子的:

$.ajax({          // 第一个AJAXtype:'GET',url:'booklist.json',success:function(booklist){console.log(booklist);$.ajax({   // 第二个AJAXtype:'GET',url:'book.json?id='+booklist.id,success:function(book){console.log(book);$.ajax({    //第三个AJAXtype:'GET',url:'comments.json?id='+book[0].id,success:function(comments){console.log(comments);},error:function(xhr,status,error){//处理一些东西}});},error:function(xhr,status,error){//处理一些东西}});},error:function(xhr,status,error){//处理一些东西}
})

三个AJAX嵌套在一起,虽然被简化了(一些数据处理直接用 console.log() 替代),但是还是看起来比较乱,一乱起来中午吃个饭回来都找不到上次写到哪里了,然而实际业务中要做的处理也绝对比这多很多。

这里先用一种比较普通的方式来处理上面那大段代码:

$.ajax({type:'GET',url:'booklist.json',success:getbook,error:handleError
});
function getbook(booklist){console.log(booklist);$.ajax({type:'GET',url:'book.json?id='+booklist.id,success:getComments,error:handleError});
}
function getComments(book){console.log(book);$.ajax({type:'GET',url:'comments.json?id='+book[0].id,success:function(comments){console.log(comments);},error:handleError});
}
function handleError(xhr,status,error){//处理一些东西
}

上面的代码封装了三个 function,看起来整齐一些了,并且所有的 error 处理都通过调用自己封装好的 handleError 去做,然而我们的代码量并没有减少多少。

下面用 Promise 对代码进行处理:

$.get(booklist.json).then(function(booklist){console.log(booklist);return $.get('book.json?id='+booklist.id);
}).then(function(book){console.log(book);return $.get('comments.json?id='+book[0].id)
}).then(function(comments){console.log(comments);
},handleError);
​
function handleError(xhr,status,error){//处理一些东西
}

Promise 通过 .then() 将函数串联在一起,它采用了同步的方式去处理异步的问题,去除了一层层的回调嵌套,error 处理只需要最后调用一次 handleError 就够了,似乎已经很好了,不过这里还有更好的方法——Generator。

下面是用 Generator 处理:

Promise.coroutine(function*(){var booklist = yield $.get('booklist.json');console.log(booklist);var book = yield $.get('book.json?id='+booklist.id);console.log(book);var comments = yield $.get('comments.json?id='+book[0].id);console.log(book);
})().catch(function(errs){//处理一些东西
})

对比第一段代码,瞬间神清气爽了!Promise.coroutine 是专门用来给 Generator 用的,作用就相当于最开始的那个带上参数的 next()。我们不需要去把回调函数嵌套在一起,或者串联在一起就能够得到想要的结果,是不是非常赞~?!!ꉂ ೭(˵¯̴͒ꇴ¯̴͒˵)౨”

References:

https://www.youtube.com/watch?v=QO07THdLWQo

https://www.youtube.com/watch?v=obaSQBBWZLk

转载于:https://my.oschina.net/u/2416429/blog/680394

ES6 Generator 初体验相关推荐

  1. Flutter初体验(二)—— 创建第一个Flutter APP

    Flutter初体验(二)--- 创建第一个Flutter APP 在第一篇文章 Flutter初体验(一)---Mac 安装配置,学习了配置 Flutter 开发环境,并运行了Demo项目,本篇根据 ...

  2. Java8初体验(二)Stream语法详解(转)

    本文转自http://ifeve.com/stream/ Java8初体验(二)Stream语法详解 感谢同事[天锦]的投稿.投稿请联系 tengfei@ifeve.com 上篇文章Java8初体验( ...

  3. webpack从入门到精通(一)初体验

    1. webpack简介 1.1 webpack是什么 webpack 是一种前端资源构建工具,一个静态模块打包器(module bundler). 在 webpack 看来, 前端的所有资源文件(j ...

  4. 【JS逆向系列】某乎x96参数与jsvmp初体验

    [JS逆向系列]某乎x96参数与jsvmp初体验 js分析 jsvmp分析 第一种解决方案-补环境 第二种解决方案-修改操作码 第三种解决方案-算法还原 参考文章 样品网址:aHR0cHM6Ly93d ...

  5. Rasa课程、Rasa培训、Rasa面试系列之:Rasa 3.x部署安装初体验

    Rasa课程.Rasa培训.Rasa面试系列之:Rasa 3.x部署安装初体验 Rasa 3.x部署安装 进入Ananconda系统,新建rasa虚拟环境 conda create --name in ...

  6. 乘风破浪React—01React初体验

    React的起源 React起源于facebook公司工程师开发时的一个bug,三个消息提示图标右上角的数字显示实时未读消息的数目,过多的操作容易产生问题. 工程师很轻易的排查并解决的bug,但是他们 ...

  7. 苹果电脑安装python3密码_mac系统安装Python3初体验

    前沿 对于iOS开发不要随便拆卸系统自带的Python,因为有很多 library 还是使用 Python2.7. 1 安装Xcode 1.1 App Store 搜索Xcode 并安装 1.2 安装 ...

  8. MapReduce编程初体验

    需求:在给定的文本文件中统计输出每一个单词出现的总次数 第一步: 准备一个aaa.txt文本文档 第二步: 在文本文档中随便写入一些测试数据,这里我写入的是 hello,world,hadoop he ...

  9. 小程序 缩放_缩放流星应用程序的初体验

    小程序 缩放 by Elie Steinbock 埃莉·斯坦博克(Elie Steinbock) 缩放流星应用程序的初体验 (First Experiences Scaling a Meteor Ap ...

最新文章

  1. 显卡不够时,如何训练大型网络
  2. R语言ggplot2可视化:ggplot2可视化两个水平条形图(horizontal)、并设置两个条形图使用共享的X轴、使用类似population pyramid可视化的方式绘制共享X轴的水平条形图
  3. shelve 序列化模块——day18
  4. 面向对象的C语言开发框架:Nesty
  5. Scrollbar中滚动条的设置
  6. 「 每日一练,快乐水题 」917. 仅仅反转字母
  7. pyhon量化数据处理小细节3---日期格式转换
  8. LeetCode 285. 二叉搜索树中的顺序后继(中序遍历)
  9. oracle 练习 50_萨克斯每天需要练习内容
  10. java如何脱离ide运行_如何脱离IDE使用自己的jar包?
  11. 微信 html5禁止拖拽,js实现微信禁止h5网页下拉,禁止微信内置浏览器下拉网页...
  12. java图书管理系统个人总结_总结:JAVA小项目——图书管理系统
  13. php写幻灯片,原生JS写的幻灯片
  14. 简历模板下载word格式 空白word简历模板下载 电子版个人简历下载
  15. 内网渗透工具-反向代理nps使用分析
  16. 最小径集的算法_最小割集Stoer-Wagner算法 | 学步园
  17. 2020 ECCV 所有论文及补充材料链接(一)
  18. 千帆竞发百日角逐,玻色量子荣获“创业北京”一等奖
  19. oracle 增量导出 导入,Oracle增量导入导出
  20. 服务器cpu占用率高怎么解决,线上服务器CPU占用率高怎么办?

热门文章

  1. NTPDATE - no server suitable for synchronization found 修复
  2. [动漫日语每天一句]01 没什么大不了的。
  3. CentOS 7系统安装配置图文详解
  4. 【干货】前端自学之路(持续更新)
  5. Spring 通过工厂方法(Factory Method)来配置bean
  6. LAMP部署搭建————重要文件备份
  7. 三种方法实现CSS三栏布局
  8. 理解haslayout
  9. [Android]手动触发OnClick事件
  10. typedef 返回类型(*Function)(参数表) ——typedef函数指针