问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

yield-js

发布网友 发布时间:2022-04-25 00:43

我来回答

2个回答

懂视网 时间:2022-04-25 05:05

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

热心网友 时间:2022-04-25 02:13

谁就是替我说话
我愿意把脑袋交给他
悬挂在他的旗哈哈杆上
一根羽毛射进石头
就能带着石头起飞
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
Linux系统安装FTP服务器 Linux系统的网络文件共享 建筑的七盏明灯的内容简介 面向对象设计七大原则 简单说 交互设计七大定律 交互设计的“根”——七大定律 交互设计原则和理论2——七大定律 七大设计原则 附近的加油站有哪些 附近的加油站有哪些地方 小妇人的影片评价 小妇人这部电影讲述的是什么? 小妇人这个电影好看吗(东方粮仓张宏伟)? 悦木之源洗面奶泡沫多吗 悦木之源洗面奶是氨基酸吗 悦木之源蘑菇水,乳液,精华用的顺序 悦木之源洗面奶敏感肌肤可以用吗? 用悦木之源一举两得洗面奶还需要卸妆吗 悦木之源洗面奶适合油皮吗 磨砂洗面奶和普通的洗面奶有什么区别,好处? 悦木之源的奇迹面膜用完是用清水洗脸还是用洗面奶洗脸? 磨砂洗面奶应多久用一次?谢谢了,大神帮忙啊 悦木之源洗面奶尾部是F88说明保质期是多久啊? 太坑*家千万不要相信网贷先给钱的,我被快鱼分期套路过钱站套路过,芝麻分期直接坑爹! 芝麻分贷款是分期还吗 芝麻信用借款需支付服务费是怎么回事 芝麻分期是骗子没办事就扣你249元? 为什么javascript需要yield 法国格勒诺布尔大学DBA难读吗? 法国格勒诺布尔大学DBA国家承认吗? 复制的全民k歌在哪里可以找到找到后又怎样发送到陌陌里面 it技术类免费的网课能学到东西吗? 最近把win10改装成了win7,但是现在fn+的一些快捷键用不了了,比如音量键 nodejs yield怎么定义 汕尾市城区华泽小额贷款有限公司怎么样? 粤财普惠金融(汕尾)融资担保股份有限公司怎么样? 为什么汕尾没有一家个人正规贷款公司? 汕尾的渔业类贷款有哪些? 你好,我是广东汕尾的,我要贷一万 汕尾哪里有贷款公司?只有身份证,而且征信花了 我没有可以抵押的产品,还可以在汕尾申请贷款吗? 华为手机人像图片都变成曝光的图片,这个要怎么设置,哪位大神知道呢,急急!谢谢&#128591; 玩了那么多手机视频桌面,还是这个好用 求流畅的安卓视频壁纸APP 手机桌面视频播放器有哪些?? 一个空调压缩机{2P}的可以接2个室内机吗? 驻车空调压缩机能平放吗? javascript 问题求助 黑枸杞真假鉴别的方式 我瞒着老公给他爸爸生孩子