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 相关文章推荐
找到一点可怜的关于dojo资料,谢谢作者!
Dec 06 Javascript
利用jQuery插件扩展识别浏览器内核与外壳的类型和版本的实现代码
Oct 22 Javascript
JavaScript操作XML 使用百度RSS作为新闻源示例
Feb 17 Javascript
js去除空格的12种实用方法
Nov 08 Javascript
js常用自定义公共函数汇总
Jan 15 Javascript
AngularJs ng-route路由详解及实例代码
Sep 14 Javascript
微信小程序 列表的上拉加载和下拉刷新的实现
Apr 01 Javascript
angular2系列之路由转场动画的示例代码
Nov 09 Javascript
Vue中使用Lodop插件实现打印功能的简单方法
Dec 19 Javascript
Antd-vue Table组件添加Click事件,实现点击某行数据教程
Nov 17 Javascript
vue+element实现动态加载表单
Dec 13 Vue.js
vue编写简单的购物车功能
Jan 08 Vue.js
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
smarty半小时快速上手入门教程
2014/10/27 PHP
PHP SplObjectStorage使用实例
2015/05/12 PHP
Yii+MYSQL锁表防止并发情况下重复数据的方法
2016/07/14 PHP
详解php中空字符串和0之间的关系
2016/10/23 PHP
扩展String功能方法
2006/09/22 Javascript
用JavaScript玩转游戏物理(一)运动学模拟与粒子系统
2010/06/19 Javascript
jquery选择器-根据多个属性选择示例代码
2013/10/21 Javascript
jquery dialog open后,服务器端控件失效的快速解决方法
2013/12/19 Javascript
jQuery使用contains过滤器实现精确匹配方法详解
2016/02/25 Javascript
AngularJS出现$http异步后台无法获取请求参数问题的解决方法
2016/11/03 Javascript
js实现刷新页面后回到记录时滚动条的位置【两种方案可选】
2016/12/12 Javascript
Html中 IFrame的用法及注意点
2016/12/22 Javascript
实现微信小程序的wxml文件和wxss文件在webstrom的支持
2017/06/12 Javascript
使用JavaScript实现链表的数据结构的代码
2017/08/02 Javascript
JS操作时间 - UNIX时间戳的简单介绍(必看篇)
2017/08/16 Javascript
AngularJS select加载数据选中默认值的方法
2018/02/28 Javascript
taro小程序添加骨架屏的实现代码
2019/11/15 Javascript
[04:21]狐狸妈带你到现场 DOTA2 TI中国区预选赛线下赛路线指引
2014/05/22 DOTA
Python使用SQLite和Excel操作进行数据分析
2018/01/20 Python
使用虚拟环境打包python为exe 文件的方法
2019/08/29 Python
Python爬虫爬取百度搜索内容代码实例
2020/06/05 Python
python 基于DDT实现数据驱动测试
2021/02/18 Python
英国Amara家居法国网站:家居装饰,现代装饰和豪华礼品
2016/12/15 全球购物
美国殿堂级滑板、冲浪、滑雪服装品牌:Volcom(钻石)
2017/04/20 全球购物
英语自荐信常用语句
2013/12/13 职场文书
小学岗位竞聘方案
2014/01/22 职场文书
骨干教师考核方案
2014/05/09 职场文书
大学应届毕业生求职信
2014/05/24 职场文书
法学求职信
2014/06/22 职场文书
2014教师教育实践活动对照检查材料思想汇报
2014/09/21 职场文书
员工开除通知书
2015/04/25 职场文书
管理失职检讨书范文
2015/05/05 职场文书
2015年出纳年终工作总结
2015/05/14 职场文书
加薪申请报告范本
2015/05/15 职场文书
煤矿隐患排查制度
2015/08/05 职场文书
2016年度师德标兵先进事迹材料
2016/02/26 职场文书