JS Generator 函数的含义与用法实例总结


Posted in Javascript onApril 08, 2020

本文实例讲述了JS Generator 函数的含义与用法。分享给大家供大家参考,具体如下:

读阮一峰老师《Generator 函数的含义与用法》总结

老师的文章通俗易懂,但是我个人理解上面有一些差,所以看了几遍之后才有呢么一点点体会

把它记录下来。

还是那句话,所有事物的出现都是为了解决对应的问题。

那么Generator出现是为了解决什么问题的呢?

在异步编程的场景下,如果有多个异步任务,如何处理他们的先后执行顺序?

举一个常见的例子,jquery的ajax请求,每一个success都是一个异步任务。

那么问题来了,如果我要保证页面渲染要在5个网络请求都回来之后再去渲染页面。

我们的代码就会变成:

$.ajax({...success:function(data){
  $.ajax({...success:function(data){
    $.ajax({...success:function(data){
      $.ajax({...success:function(data){
        $.ajax({...success:function(data){
          //do something
        }})
      }})
    }})
  }})
}})

这就是”回调函数噩梦”(callback hell)

为了解决这个问题,后来出现了Deferred和promise

两者区别不大,通过一种包装写法来减少回调函数

上面的ajax就可以写成:

ajax1 = $.ajax({...success:function(data){});
ajax2 = $.ajax({...success:function(data){});
ajax3 = $.ajax({...success:function(data){});
ajax4 = $.ajax({...success:function(data){});
ajax5 = $.ajax({...success:function(data){});
$.when(ajax1,ajax2,ajax3,ajax4,ajax5).done(function(
  //do something
)).then(function(){
  //do something2
})

1.8版本以上的jquery ajax模块默认返回Deferred对象

Deferred和promise将回调函数做拆分,将异步任务的处理和执行分成两部分完成

他们最大的问题就是代码冗余,包装之后的代码都需要通过then,done来执行后面的内容,也导致层次感不清晰

那有没有一种比较无感,简单的写法呢?

那就是协程,
我之前也是在这个地方困惑了很久,
前面说的大多日常用到过,也清楚一些原理,
关于协程用到的就少了,我们来分析下吧。

直接看一下协程的例子:

function asnycJob() {
 // ...其他代码
 var f = yield readFile(fileA);
 // ...其他代码
}

阮一峰老师的原话:

上面代码的函数 asyncJob 是一个协程,它的奥妙就在其中的 yield 命令。它表示执行到此处,执行权将交给其他协程。也就是说,yield命令是异步两个阶段的分界线。 协程遇到 yield 命令就暂停,等到执行权返回,再从暂停的地方继续往后执行。它的最大优点,就是代码的写法非常像同步操作,如果去除yield命令,简直一模一样。

之前没理解的原因就是没好好读这两句话,今认真看了一下,茅塞顿开。重要的有这么几点

首先asnycJob这个方法就是一个协程

yield相当于return,会返回当前程序的执行状态

当执行到yield,程序挂起等待返回后继续执行。

挂起这段时间去执行其他协程函数

Generator函数是ES6对协程函数的实现,

Generator函数的特点就是可以暂停代码执行。

跟协程函数一样,遇到yield关键字就暂停代码执行,

跟普通函数的区别在于Generator函数不会反悔结果,而是返回指针对象,

通过指针的next方法移动指针指向下一个yield关键字位置。

也就是说Generator函数的分阶段执行是由next方法控制的。

使用了Generator函数之后会对我们的代码有多大的改变呢?

fangction* gen(){
  var url = 'user/get/info';
  var data = yield $.get({url:url});
  console.log(data.userName);
}

你不需要担心远程接口的返回时机,完全按照同步的方式写代码就行。

但是也有缺点,Generator函数把一步操作做的很简洁,但对流程的管理却不方便,

上面的例子如何执行?

var g = gen();
g.next();
g.next();

next 方法的作用是分阶段执行 Generator 函数。每次调用 next 方法,会返回一个对象,

表示当前阶段的信息( value 属性和 done 属性)。value 属性是 yield 语句后面表达式的值,表示当前阶段的值;

done 属性是一个布尔值,表示 Generator 函数是否执行完毕,即是否还有下一个阶段。

你需要执行两次.next方法,来将你的Generator函数执行完毕。

关于如何自动化异步任务的流程管理,就需要co,thunk,async的帮助了

原文:Generator 函数的含义与用法

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容可查看本站专题:《JavaScript常用函数技巧汇总》、《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
JS简单实现登陆验证附效果图
Nov 19 Javascript
wap手机图片滑动切换特效无css3元素js脚本编写
Jul 28 Javascript
IE6兼容透明背景图片及解决方案
Aug 19 Javascript
js实现鼠标点击文本框自动选中内容的方法
Aug 20 Javascript
javascript中错误使用var造成undefined
Mar 31 Javascript
jQuery基础知识点总结(DOM操作)
Jun 01 Javascript
Vue组件的使用教程详解
Jan 05 Javascript
基于vue v-for 循环复选框-默认勾选第一个的实现方法
Mar 03 Javascript
vue父组件异步获取数据传给子组件的方法
Jul 26 Javascript
React中this丢失的四种解决方法
Mar 12 Javascript
解决vue watch数据的方法被调用了两次的问题
Nov 07 Javascript
详细聊聊vue中组件的props属性
Nov 02 Vue.js
Vue列表循环从指定下标开始的多种解决方案
Apr 08 #Javascript
《javascript设计模式》学习笔记七:Javascript面向对象程序设计组合模式详解
Apr 08 #Javascript
vue开发移动端底部导航条功能
Apr 08 #Javascript
《javascript设计模式》学习笔记五:Javascript面向对象程序设计工厂模式实例分析
Apr 08 #Javascript
vue实现表单未编辑或未保存离开弹窗提示功能
Apr 08 #Javascript
JS快速实现简单计算器
Apr 08 #Javascript
javascript中contains是否包含功能实现代码(扩展字符、数组、dom)
Apr 07 #Javascript
You might like
在PHP中使用redis
2013/11/04 PHP
php中Session的生成机制、回收机制和存储机制探究
2014/08/19 PHP
PHP常用的排序和查找算法
2015/08/06 PHP
学习php设计模式 php实现装饰器模式(decorator)
2015/12/07 PHP
基于thinkPHP3.2实现微信接入及查询token值的方法
2017/04/18 PHP
php微信支付之公众号支付功能
2018/05/30 PHP
PHP实现的微信公众号扫码模拟登录功能示例
2019/05/30 PHP
EXTJS记事本 当CompositeField遇上RowEditor
2011/07/31 Javascript
在百度知道团队中快速审批新成员的js脚本
2014/02/02 Javascript
对new functionName()定义一个函数的理解
2014/05/22 Javascript
JavaScript跨浏览器获取页面中相同class节点的方法
2015/03/03 Javascript
Shell脚本实现Linux系统和进程资源监控
2015/03/05 Javascript
基于jquery实现最简单的选项卡切换效果
2016/05/08 Javascript
详解微信小程序 wx.uploadFile 的编码坑
2017/01/23 Javascript
jQuery通过改变input的type属性实现密码显示隐藏切换功能
2017/02/08 Javascript
Node.JS中事件轮询(Event Loop)的解析
2017/02/25 Javascript
Vue CLI3 开启gzip压缩文件的方式
2018/09/30 Javascript
vue 使用vue-i18n做全局中英文切换的方法
2018/10/29 Javascript
[01:09:24]Ti4开幕式
2014/07/19 DOTA
[00:34]拔城逐梦,热血永恒!2020(秋)完美世界城市挑战赛报名开启
2020/10/09 DOTA
对pandas将dataframe中某列按照条件赋值的实例讲解
2018/11/29 Python
Django使用AJAX调用自己写的API接口的方法
2019/03/06 Python
Python学习笔记之列表和成员运算符及列表相关方法详解
2019/08/22 Python
五分钟带你搞懂python 迭代器与生成器
2020/08/30 Python
解决Ubuntu18中的pycharm不能调用tensorflow-gpu的问题
2020/09/17 Python
实例教程 HTML5 Canvas 超炫酷烟花绽放动画实现代码
2014/11/05 HTML / CSS
设计师个人求职信范文
2014/02/02 职场文书
你的创业计划书怎样才能打动风投
2014/02/06 职场文书
科级干部考察材料
2014/02/15 职场文书
信息服务专业毕业生求职信
2014/03/02 职场文书
九一八事变演讲稿
2014/09/05 职场文书
领导班子“四风问题”“整改方案
2014/10/02 职场文书
县长群众路线对照检查材料思想汇报
2014/10/02 职场文书
2015暑假假期总结
2015/07/13 职场文书
《乌鸦喝水》教学反思
2016/02/19 职场文书
告别网页搜索!教你用python实现一款属于自己的翻译词典软件
2021/06/03 Python