JavaScript中yield实用简洁实现方式


Posted in Javascript onJune 12, 2010

刚才忽然灵机一动,迭代器我们很少会真的直接傻乎乎的next去遍历的,那为什么一定要实现这个傻乎乎的next呢?直接实现each,这样,这样反过来,Yeah,一通百通,不一会儿就写出了第一个超简洁版本:

function yieldHost(yieldFunction) 
{ 
return function (processer) 
{ 
var yield = function (result) 
{ 
processer(result) 
}; 
yieldFunction(yield); 
}; 
}

思路一换,代码真简洁。
先附上例子,然后来谈原理。
首先我们需要一个函数来进行枚举,像这样:
function fun(yield) 
{ 
for (var i = 0; i < 100; i++) 
yield(i); 
}

或是这样:
function fun(yield) 
{ 
yield(1); 
yield(2); 
yield(3); 
}

由于实现方式与C#的不同,所以在循环体内也不用什么yield break或是yield continue这样的语法,直接break或是continue就好了。
然后是实际的运用,yieldHost函数可以将上面的符合要求的fun函数转换为一个枚举器:
var enumerator = yieldHost(fun);
这个枚举器其实也是一个函数,像jQuery的each函数一样,接收一个处理函数来处理枚举:
enumerator(function (item) 
{ 
window.alert(item); 
});

接下来谈谈原理。
对于传统的枚举器来说,我们会认为枚举器应该在每次调用返回一个值,这就是next方法,但就像陈子瀚说的,这需要在yield的时候把函数停住,虽然可以实现,但真的很麻烦。
但!事实上我发现,大多数时候,我们都是用foreach这样的语法来访问枚举器的。这样一来就给了我一个非常讨巧的办法,不实现next方法,而是实现each方法。
each方法和next的方法的区别在哪里呢?熟悉jQuery的朋友就会知道,each方法其实可以视为将next倒过来,不是返回枚举值,而是接收一个函数,把枚举值当作参数传进去。
正是这一倒,所有问题都迎刃而解了。我们没有必要去暂停一个函数的执行,只需要将处理枚举值的逻辑注到这个函数里面去就完了。所以事实上这里的yieldHost就是完成了一个倒装的工作,把enumerator接收的那个函数(也就是window.alert( item ),注到了枚举函数中(即fun)。最终执行的效果就像是这样:
function fun(yield) 
{ 
window.alert(1); 
window.alert(2); 
window.alert(3); 
}

所以就诞生了这个超简洁的实现。
有了这个超简洁的实现,下一步就是实现像jQuery的each方法一样的return true代表break和return false代表continue的功能了,只有具备了这样的功能,才能处理无穷集,或是实现TakeWhile之类的功能。
老实说我对JavaScript的研究并不透彻,只想到了一个使用异常打断的办法,这就是第二个版本的yieldHost:
function yieldHost(yieldFunction) 
{ 
var exception = Math.random(); 
return function (processer) 
{ 
try 
{ 
yieldFunction(function (result) 
{ 
if (processer(result)) 
throw exception; 
}); 
} 
catch (e) 
{ 
if (e !== exception) 
throw e; 
} 
}; 
}

显然这并不完美,但我实在想不出更好的办法。
接下来在这个基础上实现Select、Where什么,其实是非常简单的事情,给出一个我的Select的实现:
function Select(enumerator, selector) 
{ 
return function (fun) 
{ 
enumerator(function (item) 
{ 
return fun(selector(item)); 
}); 
} 
}

至于,这个Select怎么修改成连写的版本,即:
enumerator.Select( selector )( processor );
我觉得这对JavaScript而言真不是一件很难的事情啊。。。。
只是,过早的引入语法友好,会把JavaScript变得很复杂难看。所以,这个留给大家去玩吧。

Javascript 相关文章推荐
Javascript与flash交互通信基础教程
Aug 07 Javascript
Javascript 强制类型转换函数
May 17 Javascript
javascript Demo模态窗口
Dec 06 Javascript
jquery 3D球状导航的文章分类
Jul 06 Javascript
JS数组(Array)处理函数整理
Dec 07 Javascript
javascript中定义类的方法详解
Feb 10 Javascript
JS获取iframe中marginHeight和marginWidth属性的方法
Apr 01 Javascript
JQuery实现图片轮播效果
May 08 jQuery
深究AngularJS之ui-router详解
Jun 13 Javascript
JS点击缩略图整屏居中放大图片效果
Jul 04 Javascript
vue的for循环使用方法
Feb 12 Javascript
layui 实现表单和文件上传一起传到后台的例子
Sep 16 Javascript
EasySlider 基于jQuery功能强大简单易用的滑动门插件
Jun 11 #Javascript
JavaScript 开发规范要求(图文并茂)
Jun 11 #Javascript
cnblogs TagCloud基于jquery的实现代码
Jun 11 #Javascript
Js setInterval与setTimeout(定时执行与循环执行)的代码(可以传入参数)
Jun 11 #Javascript
js鼠标左右键 键盘值小结
Jun 11 #Javascript
JavaScript接口实现代码 (Interfaces In JavaScript)
Jun 11 #Javascript
JavaScript的单例模式 (singleton in Javascript)
Jun 11 #Javascript
You might like
phpfans留言版用到的install.php
2007/01/04 PHP
php获取mysql数据库中的所有表名的代码
2011/04/23 PHP
php实现的漂亮分页方法
2014/04/17 PHP
详解在PHP的Yii框架中使用行为Behaviors的方法
2016/03/18 PHP
javascript中的对象和数组的应用技巧
2007/01/07 Javascript
JS中confirm,alert,prompt函数使用区别分析
2010/04/01 Javascript
js更优雅的兼容
2010/08/12 Javascript
解决遍历时Array.indexOf产生的性能问题
2012/07/03 Javascript
文本框倒叙输入让输入框的焦点始终在最开始的位置
2014/09/01 Javascript
JavaScript SHA512&amp;SHA256加密算法详解
2015/08/11 Javascript
AngularJS通过ng-route实现基本的路由功能实例详解
2016/12/13 Javascript
详解JavaScript树结构
2017/01/09 Javascript
微信小程序自定义模态对话框实例详解
2017/08/16 Javascript
vue2.0 根据状态值进行样式的改变展示方法
2018/03/13 Javascript
详解如何制作并发布一个vue的组件的npm包
2018/11/10 Javascript
JavaScript使用面向对象实现的拖拽功能详解
2019/06/12 Javascript
Vue强制组件重新渲染的方法讨论
2020/02/03 Javascript
微信公众号中的JSSDK接入及invalid signature等常见错误问题分析(全面解析)
2020/04/11 Javascript
python 遍历字符串(含汉字)实例详解
2017/04/04 Python
python多维数组切片方法
2018/04/13 Python
Python第三方库face_recognition在windows上的安装过程
2019/05/03 Python
基于python爬取有道翻译过程图解
2020/03/31 Python
HTML5 canvas 基本语法
2009/08/26 HTML / CSS
比利时的在线灯具店:Lampen24.be
2019/07/01 全球购物
TALLY WEiJL法国网上商店:服装、时装及配饰
2019/08/31 全球购物
家乐福台湾线上购物网:Carrefour台湾
2020/09/15 全球购物
惠而浦美国官网:Whirlpool.com
2021/01/19 全球购物
品质主管的岗位职责
2013/12/04 职场文书
《散步》教学反思
2014/03/02 职场文书
股东协议书
2014/04/14 职场文书
计算机系统管理员求职信
2014/06/20 职场文书
校园游戏活动新闻稿
2014/10/15 职场文书
给医院的感谢信
2015/01/21 职场文书
创业计划书之甜品店
2019/09/18 职场文书
iSCSI服务器CHAP双向认证配置
2022/04/01 Servers
2022新作动画《福星小子》释出宣传影片 加入内田真礼&宫野真守配音演出
2022/04/08 日漫