原题还是老赵的:

http://blog.zhaojie.me/2010/06/code-for-fun-iterator-generator-yield-in-javascript.html

原以为是一个蛮复杂的题目,想了许久没思路,当然要实现绝对能实现,但如果分析JavaScript脚本或是动态产生代码,都太复杂了。

刚才忽然灵机一动,迭代器我们很少会真的直接傻乎乎的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变得很复杂难看。所以,这个留给大家去玩吧。

公司招聘,应老大要求在文章末尾附上顺风车广告一条,不喜勿入:http://job.cnblogs.com/offer/7490/

转载于:https://www.cnblogs.com/Ivony/archive/2010/06/08/1754390.html

在JavaScript中实现yield,实用简洁实现方式。相关推荐

  1. javaScript中创建数组的3种方式

    JS数组定义及详解 javascript如何定义数组? 直接上代码和截图 //javaScript中创建数组的3种方式 //方式1 var names = ["令狐冲", &quo ...

  2. JavaScript中判断为整数的多种方式

    JavaScript中不区分整数和浮点数,所有数字内部都采用64位浮点格式表示,和Java的double类型一样.但实际操作中比如数组索引.位操作则是基于32位整数. 方式一.使用取余运算符判断 任何 ...

  3. javascript中定义事件的三种方式

    在javascript中,可以为某个元素指定事件,指定的方式有以下三种: 1.在html中,使用onclick属性 2.在javascript中,使用onclick属性 3.在javascipt中,使 ...

  4. JavaScript中的(内置)方式来检查字符串是否为有效数字

    我希望在与旧的VB6 IsNumeric()函数相同的概念空间中有东西吗? #1楼 引用: isNaN(num)//如果变量不包含有效数字,则返回true 如果您需要检查前导/后缀空格,例如,当需要一 ...

  5. JavaScript中定义对象的几种方式

    JavaScript中没有类的概念,只有对象. 在JavaScript中定义对象可以采用以下5种方式(附加改进方式): 1.基于已有对象扩充其属性和方法 2.工厂方式 3.构造函数方式 4.原型(&q ...

  6. html中数组的定义,javascript中数组定义的几种方式是什么?

    javascript中怎么定义数组?下面本篇文章给大家介绍一下javascript数组定义的几种方法.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 1.什么是数组 数组就是一组数据 ...

  7. 【JS】JavaScript中创建数组的6种方式(代码示例合集)

    创建数组的6种方式 <!DOCTYPE html> <html lang="en"><head><meta charset="U ...

  8. 在javascript中使用yield

    yield 关键字用来暂停和恢复一个生成器函数((function* 或遗留的生成器函数). /*** 在控制台每隔1秒,依次输出* 0,1,2,3,4*///延迟1秒返回n function del ...

  9. JavaScript中this的五种绑定方式详解

    1 this的五种绑定方式 1.1 默认绑定 默认绑定是指当函数调用时,没有为其指定对象上下文,此时会将该函数的this绑定到全局对象(window对象).自ES5有了严格模式之后,默认绑定方式又分为 ...

最新文章

  1. sklearn 朴素贝叶斯分类示例
  2. leveldb源码分析:Open启动流程
  3. python第四十一天---作业:简单FTP
  4. python绘制双Y轴折线图以及单Y轴双变量柱状图
  5. 深度学习(10)TensorFlow基础操作六: 数学运算
  6. 如何在anaconda环境下安装tensorflow/pytorch/keras等
  7. linux ls 中文乱码_每天一个linux命令:Linux文件类型与扩展名
  8. C语言单链表的应用,单链表应用
  9. 使用Swift触摸任意位置以关闭iOS键盘
  10. android之Activity关闭返回数据到启动他的页面
  11. Mac键盘突然停止响应如何处理
  12. mysql .pem 文件_对于https ssl中的pem文件和key 文件的理解
  13. 小公司个人技术成长路线思考
  14. Cypress 增加自定义header访问
  15. [c++] 什么是平凡类型,标准布局类型,POD类型,聚合体
  16. SHIO世硕科技马新云携全体员工:2021,在此感谢所有的一切!
  17. 用RunASDate解决SAS 9.4许可证过期的问题
  18. 基于RWEQ模型的土壤风蚀模数估算及其变化归因分析
  19. BW增强-BAdI(初级)
  20. vector的骚操作

热门文章

  1. ora-01740: 标识符中缺失双引号_sql语句中单引号的使用
  2. 谈谈对python 和其他语言的区别_谈谈Python和其他语言的区别
  3. 华为u8825d解锁工具_黔隆科技刷机教程VIVOX20PLUSA忘记密码刷机解锁降级救砖解屏幕锁账户锁教程...
  4. Java如何连接openvas_gas: chinese Gui for openvAS(GAS)
  5. dorado7ajax,Dorado7
  6. android webview 截图,Android获取webView快照与屏幕截屏的方法 -电脑资料
  7. (5) 百度2011研发工程师笔试卷
  8. 飞机大战-控制飞机左右移动二
  9. jQuery前端教程-张晨光-专题视频课程
  10. java编程double相乘_浅谈Java double 相乘的结果偏差小问题