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 7758console.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

转载于:https://www.cnblogs.com/liumingwang/p/10216073.html

javascript生成器相关推荐

  1. [译] 什么是 JavaScript 生成器?如何使用生成器?

    原文地址:What are JavaScript Generators and how to use them 原文作者:Vladislav Stepanov 译文出自:掘金翻译计划 本文永久链接:g ...

  2. JavaScript生成器函数(generator function)

    JavaScript生成器函数(generator function) 注意:数组推导式和生成器推导式建议都不要使用.都是非标准语法. 可以使用生成器函数(generator function) 语法 ...

  3. JavaScript 生成器函数

    JavaScript 生成器函数是一种特殊的函数,它可以返回一个迭代器.使用生成器函数,可以在函数执行期间暂停并返回一个值,并在之后继续执行函数. 使用生成器函数时,需要在函数名前面加上一个星号 (* ...

  4. JavaScript 生成器Generator

    目录 定义 语法 使用 Generator.prototype.next() Generator.prototype.return() Generator.prototype.throw() 使用场景 ...

  5. javascript 生成器函数 function*

    今天看了一下这块的东西,文档不是很好理解.但是完完整整看下来,文档还是很全的. 这里算是总结一下在看生涩的文档之前可以了解的东西,方便看文档的时候好理解. 1,什么是生成器函数(function*) ...

  6. 细说JavaScript异步函数发展历程

    2019独角兽企业重金招聘Python工程师标准>>> < The Evolution of Asynchronous JavaScript >外文梳理了JavaScri ...

  7. TypeScript入门教程 之 生成器函数

    TypeScript入门教程 之 生成器函数 生成器函数 function *是用于创建生成器函数的语法.调用generator函数将返回一个generator对象.发电机对象如下刚刚所述迭代器接口( ...

  8. ES5 to ESNext —  自 2015 以来 JavaScript 新增的所有新特性

    type: FrontEnd title: ES5 to ESNext - here's every feature added to JavaScript since 2015 link: medi ...

  9. javaScript ES6-ES11新特性总结

    ES6-ES11新特性知识点 一.ES6 1.查看ES6兼容性 http://kangax.github.io/compat-table/es6/ 可查看兼容性 2.let定义变量 快速入门: //特 ...

最新文章

  1. 电子时钟单片机c语言程序,51单片机电子时钟C语言程序
  2. STL的Vector, List and Deque
  3. 【CV】OpenCV 入门之旅
  4. mysql安装后配置
  5. Python标准库datetime中4种基本对象的用法
  6. 获取指定目录下的所有文件名,包括子目录函数
  7. java垃圾回收 分代_Java-垃圾回收机制-通用的分代垃圾回收机制
  8. 对付镜像网站非常有效的办法
  9. 算法导论-15.5-4
  10. 实验3-1 求一元二次方程的根 (20 分)
  11. https://www.runoob.com/python/python-variable-types.html
  12. 接口与事件之图形界面的认证登录
  13. C++读取excel表格
  14. 学神经网络需要什么基础,神经网络需要什么基础
  15. windows自带黑体_微软黑体下载-微软黑体官方下载[字体下载]-华军软件园
  16. 图片在线转换成word免费版
  17. 【转】web.xml不同版本的头
  18. Fandis COSTECH A17M23SWB MT0 AC220V 50HZ 42W
  19. 网站/APP 流量分析、点击流分析、用户访问分析
  20. hotmail邮箱pop3服务器设置方法

热门文章

  1. masm5安装教程_汇编语言程序环境搭建masm+debug64位 win10/7
  2. OpenCV:OpenCV图像旋转的代码
  3. 软件构架师的十大特点
  4. 科学存储数据格式-HDF5
  5. java Base64转码传图到C#
  6. 什么是 Webpack?【Webpack Book 翻译】
  7. linux/unix编程手册-16_20
  8. 中国移动2016年NAT独立设备集采:迪普科技连续三年入围
  9. 【完全开源】微信客户端.NET版
  10. PHP快速排序(原地切分)