next()方法

如果给next方法传参数, 那么这个参数将会作为上一次yield语句的返回值 ,这个特性在异步处理中是非常重要的, 因为在执行异步代码以后, 有时候需要上一个异步的结果, 作为下次异步的参数, 如此循环::

Generator函数返回的Iterator执行next()方法以后, 返回值的结构为:

{
value : "value", //value为返回的值
done : false //done的值为一个布尔值, 如果Interator未遍历完毕, 他会返回false, 否则返回true;
}

如果给next方法传参数, 那么这个参数将会作为上一次yield语句的返回值 ,这个特性在异步处理中是非常重要的, 因为在执行异步代码以后, 有时候需要上一个异步的结果, 作为下次异步的参数, 如此循环

throw方法

如果执行Generator生成器的throw()方法, 如果在Iterator执行到的yield语句写在try{}语句块中, 那么这个错误会被内部的try{}catch(){}捕获 ,如果Interator执行到的yield没有写在try{}语句块中, 那么这个错误会被外部的try{}catch(){}语句块捕获;

<script>
var g = function* () {
try {
yield;
} catch (e) {
console.log('内部捕获0', e);
}
}; var i = g();
i.next(); //让代码执行到yield处;
try {
i.throw('a');
} catch (e) {
console.log('外部捕获', e);
}
</script>
function *ylj(){
try{
var a1 = yield 1;
var a2 = yield a1+1;
var a3 = yield a2 + 2;
console.log('over');
}catch(err){
console.log(err);
}
var a4 = yield 7758
console.log('out');
} var it = ylj();
console.log(it.next());
console.log(it.throw('error'))
console.log(it.next())
/////////////////控制台显示结果
{value: 1, done: false}
error
{value: 7758, done: false}
out
{value: undefined, done: true}

注意:it.throw会向生成器抛出一个错误,如果生成器内部有try...catch,立刻跳出try{},执行catch内的函数,就能够捕获错误,如果try..catch外还有yield,it.throw还会自动执行try..catch外的第一个yield,并返回一个对象,例如"{value: 7758, done: false}"。

return()方法

function* gen() {
yield 0;
yield 1;
yield 2;
yield 3;
};
let g = gen();
console.log(g.return("heheda")); //输出:{ value: 'heheda', done: true }

如果执行Iterator的return()方法, 那么这个迭代器的返回会被强制设置为迭代完毕, 执行return()方法的参数就是这个Iterator的返回值,此时done的状态也为true:

1. 迭代消息传递

function *foo(x) {
var y = x * (yield);
return y;
}
var it = foo( 6 );
// 启动foo(..)
it.next();
var res = it.next( 7 );
res.value; // 42

首先,传入 6 作为参数 x 。然后调用 it.next() ,这会启动 *foo(..) 。在 *foo(..) 内部,开始执行语句 var y = x .. ,但随后就遇到了一个 yield 表达式。它就会在这一点上暂停 *foo(..) (在赋值语句中间!),并在本质上要求调用代码为 yield表达式提供一个结果值。接下来,调用 it.next( 7 ) ,这一句把值 7 传回作为被暂停的yield 表达式的结果。

一般来说,需要的 next(..) 调用要比 yield 语句多一个,前面的代码片段有一个 yield 和两个 next(..) 调用

因为第一个 next(..) 总是启动一个生成器,并运行到第一个 yield 处。不过,是第二个next(..) 调用完成第一个被暂停的 yield 表达式,第三个 next(..) 调用完成第二个 yield ,以此类推

最后一个next(),即如果done属性为true,则返回return 的值,如果没有就返回undefined。

生成器的起始处我们调用第一个 next() 时,还没有暂停的 yield 来接受这样一个值。规范和所有兼容浏览器都会默默丢弃传递给第一个 next() 的任何东西。传值过去仍然不是一个好思路,因为你创建了沉默的无效代码,这会让人迷惑。因此,启动生成器时一定要用不带参数的 next()。

二、

for..of 循环在每次迭代中自动调用 next() ,它不会向 next() 传入任何值,并且会在接收到 done:true 之后自动停止。这对于在一组数据上循环很方便。

除了构造自己的迭代器,许多 JavaScript 的内建数据结构(从 ES6 开始),比如 array ,也有默认的迭代器:

var a = [1,3,5,7,9];
for (var v of a) {
console.log( v );
}
// 1 3 5 7 9

for..of 循环向 a 请求它的迭代器,并自动使用这个迭代器迭代遍历 a 的值。

三、

function foo(x, y) {
ajax(
"http://some.url.1/?x=" + x + "&y=" + y,
function(err, data) {
if (err) {
// 向*main()抛出一个错误
it.throw(err);
} else {
// 用收到的data恢复*main()
it.next(data);
}
}
);
} function* main() {
try {
var text = yield foo(11, 31);
console.log(text);
} catch (err) {
console.error(err);
}
}
var it = main();
var text = yield foo( 11, 31 );
console.log( text );

我们调用了一个普通函数 ajax(..) ,而且显然能够从 Ajax 调用中得到 text ,即使它是异步的。

但是,下面这段代码不能工作!你能指出其中的区别吗?区别就在于生成器中使用的 yield 。

var data = foo( "..url 1.." );
console.log( data );

正是这一点使得我们看似阻塞同步的代码,实际上并不会阻塞整个程序,它只是暂停或阻塞了生成器本身的代码。

这意味着什么。我们在生成器内部有了看似完全同步的代码(除了 yield 关键字本身),但隐藏在背后的是,除开生成器,在foo函数或大环境内的运行可以完全异步。

同步处理错误:

try {
var text = yield foo( 11, 31 );
console.log( text );
}
catch (err) {
console.error( err );
}

yield让赋值语句暂停来等待 foo(..) 完成,使得响应完成后可以被赋给 text 。 yield 暂停也使得生成器能够捕获错误。通过这段前面列出的代码把错误抛出到生成器中:

前端交流群请加群:277942610

javascript生成器的更多相关文章

  1. Javascript生成器函数

    function* 这种声明方式(function关键字后跟一个星号)会定义一个生成器函数 (generator function),它返回一个Generator 对象 示例: function* g ...

  2. JavaScript生成器+随机数的使用

    function* getIndex(indexList){ var len = indexList.length; var m; while(indexList.length > 0){ m ...

  3. 说一说javascript的异步编程

    众所周知javascript是单线程的,它的设计之初是为浏览器设计的GUI编程语言,GUI编程的特性之一是保证UI线程一定不能阻塞,否则体验不佳,甚至界面卡死. 所谓的单线程就是一次只能完成一个任务, ...

  4. ES6迭代器和生成器

    一.迭代器 JavaScript 原有的表示"集合"的数据结构,主要是数组(Array)和对象(Object),ES6 又添加了Map和Set.这样就需要一种统一的接口机制,来处理 ...

  5. Node.js最新技术栈之Promise篇

    前言 大家好,我是桑世龙,github和cnodejs上的i5ting,目前在天津创业,公司目前使用技术主要是nodejs,算所谓的MEAN(mongodb + express + angular + ...

  6. ES6新特性:Javascript中Generator(生成器)

    ES6的很多特性都跟Generator扯上关系,而且实际用处比较广, 包含了任何需要异步的模块, 比如ajax, filesystem, 或者数组对象遍历等都可以用到: Generator的使用: G ...

  7. JavaScript 高阶函数 + generator生成器

    map/reduce map()方法定义在JavaScript的Array中,我们调用Array的map()方法,传入我们自己的函数,就得到了一个新的Array作为结果: function pow(x ...

  8. JavaScript学习笔记(十三)——生成器(generator)

    在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意! 如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/ ...

  9. Javascript中Generator(生成器)

    阅读目录 Generator的使用: yield yield* next()方法 next()方法的参数 throw方法() return()方法: Generator中的this和他的原型 实际使用 ...

随机推荐

  1. Unable to find a single main class from the following candidates ,显示有两个main class

    由于基础框架是用的网上down的源码,我将项目名字改了,估计没有进行maven clean,本地调试的时候没有问题. 当发布时候,执行maven install 一直提示上述错误. 解决办法:1.ma ...

  2. zookeeper选举流程

    如何在zookeeper集群中选举出一个leader,zookeeper使用了三种算法,具体使用哪种算法,在配置文件中是可以配置的,对应的配置项是”electionAlg”,其中1对应的是Leader ...

  3. [原创] debian 9.3 搭建seafile企业私有网盘

    [原创] debian 9.3 搭建seafile企业私有网盘 需求是这样的, 个人疲惫于 "成为大伙的文件中转站" ,公司不管大大小小的文件,都要打电话过来“转个xx文件”.“帮 ...

  4. 项目管理第一篇(PROJECT MANAGEMENT A Systems Approach to Planning, Scheduling, and Controlling)

    请把梦想和野心带上,这是我哥对我说的. 几年下来,人浑浑噩噩,梦想和野心像锋利的石头在水中慢慢被磨平,今天就再次记住,不要让焦虑和失望伴随着人生和家庭. 这是H A R O L D K E R Z N ...

  5. UWP简单测试

    随便写下,试试.Net Core与UWP开发,后台WCF XAML <Page x:Class="App3.MainPage" xmlns="http://sche ...

  6. position:fixed失效情况

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. Codeforces Round #436 D. Make a Permutation!

    题意:给你n个数字,其中可能有相同的数字,要求你用其他的数字替换这些相同的数字,使得所得的序列字典序最小. Examples Input 43 2 2 3 Output 21 2 4 3 Input ...

  8. Spring MVC随笔记录

    根据https://blog.csdn.net/abc997995674/article/details/80353410整理 @ModelAttribute 可以用在方法.方法参数上,也可以和@re ...

  9. pwnable.kr-bof-witeup

    根据原程序可知,输入overflowme变量覆盖key变量即可,所以接下来应该看俩变量的距离,从而构造覆盖的payload. 嗯,他们相差了52个地址,overflowme变量在低地址,存放函数的栈中 ...

  10. Python学习笔记5程序的控制结构

    1.分支结构 (1)单分支结构 (2)二分支结构 (3)多分支结构 条件判断 (4)程序的异常处理 2.实例:身体质量指数BMI 思路一(国内,稍作修改就是国际): 思路二: height,weigh ...