前言

generotor 和 普通函数的不同在于function 的时候加了一个*,

是的,我们看到es5的一个陌生关键字,yield,这个是不寻常的,为什么这么说呢?

这个在c#中,很常见的一个关键字,下面就来解释一下js中的。

正文

function* gen() {
yield "1";
yield "2"
}
var iterator = gen();
console.log(iterator);
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

这个玩意儿如果运行的话,会返回一个Iterator实例, 然后再执行Iterator实例的next()方法, 那么这个函数才开始真正运行,

并把yield后面的值包装成固定对象并返回,直到运行到函数结尾, 最后再返回undefined;

我为什么这么说呢?改一下代码:

function* gen() {
yield "1";
console.log('123');
yield "2";
}
var iterator = gen();
console.log(iterator);
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

这个可以看图说话我就不多说了。

下面介绍一下其他的一些特性。

yield*

yield* 表达式用于委托给另一个generator 或可迭代对象。

下面是委托为另一个:generator

function* foo() {
yield 0;
yield 1;
}
function* bar() {
yield 'x';
yield* foo();
yield 'y';
}
for (let v of bar()) {
console.log(v);
};

实际上上面就说了可以委托为任何可迭代的对象。

function* g3() {
yield* [1, 2];
yield* "34";
yield* arguments;
}
var iterator = g3(5, 6);
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: "3", done: false }
console.log(iterator.next()); // { value: "4", done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: 6, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

return

The return() method returns the given value and finishes the generator.

function* gen() {
yield 1;
yield 2;
yield 3;
}
const g = gen();
g.next(); // { value: 1, done: false }
g.return('foo'); // { value: "foo", done: true }
g.next(); // { value: undefined, done: true }

throw()

The throw() method resumes the execution of a generator by throwing an error into it and returns an object with two properties done and value.

function* gen() {
while (true) {
try {
yield 42;
} catch (e) {
console.log('Error caught!');
}
}
} const g = gen();
g.next();
// { value: 42, done: false }
g.throw(new Error('Something went wrong'));
// "Error caught!"
// { value: 42, done: false }

next

next 分为带参数和不带参数,不带参数的我就不说了,说下带参数的。

function* foo(x) {
var y = 2 * (yield (x + 1));
console.log(y)
var z = yield (y / 3);
console.log(x);
console.log(z);
console.log(y);
return (x + y + z);
} var b = foo(5);
console.log(b.next()); // { value:6, done:false }
console.log(b.next(12)); // { value:8, done:false }
console.log(b.next(13)); // { value:42, done:true }

惊喜不惊喜意外不意外?

过程其实也很简单,比如说第二个传入了12。

这个运行过程其实是从第一个yiled 开始运行的,也就是这个12会替换(x + 1)

这样y就等于24了,然后yield (y / 3) 就是8了。

后续也是这样。

应用

<script>
"use strict";
function* main() {
var result = yield request("http://www.filltext.com?rows=10&f={firstName}");
console.log(result);
//do 别的ajax请求;
}
function request(url) {
var r = new XMLHttpRequest();
r.open("GET", url, true);
r.onreadystatechange = function () {
if (r.readyState != 4 || r.status != 200) return;
var data = JSON.parse(r.responseText);
//数据成功返回以后, 代码就能够继续往下走了;
it.next(data);
};
r.send();
}
var it = main();
it.next();
console.log("执行到这儿啦");
</script>

我把打印放出来:

其实上面可能存在疑惑的地方,那就是为什么console.log(result);会打印出it.next(data);中data的结果。

其实非常简单,当var result = yield request("http://www.filltext.com?rows=10&f={firstName}");执行完毕的时候,因为没有next,然后就被阻塞了。

那么更具上面next的特性。it.next(data)中的data会替换:yield request("http://www.filltext.com?rows=10&f={firstName}"),那么result的结果就是data。

实现了我们async和await的效果。

最新文章

  1. OpenGL编程指南(第七版)
  2. Spring中加载xml配置文件的六种方式
  3. 输入n个整数,输出其中最小的k个
  4. AngularJS 表单提交后显示验证信息与失焦后显示验证信息
  5. poj City Horizon (线段树+二分离散)
  6. SVN服务器搭建和使用(二)
  7. WordPress Event Easy Calendar插件多个跨站请求伪造漏洞
  8. google的西联汇款可以使用工行代收
  9. Codeforces Round #316 (Div. 2A) 570A Elections
  10. 中科同向备份软件Heartsone-backup(足足16个软件,可差异化备份虚拟机)
  11. Aforge.net 一个专门为开发者和研究者基于C#框架设计
  12. android入门:activity之间跳转,并且回传参数
  13. Xilinx ISE 14.1中模拟True Dual Port RAM例子
  14. linux几条常用的命令
  15. FlashFXP用到的功能
  16. golang二进制bit位的常用操作
  17. MySQL 5.7 安装指南
  18. [转] AES,SHA1,DES,RSA,MD5区别
  19. Python - 统计一篇文章中单词的频率
  20. [js]js的表单验证onsubmit方法

热门文章

  1. python-用户输入和while循环
  2. Asp.Net Core 3.1 学习3、Web Api 中基于JWT的token验证及Swagger使用
  3. 2019-2020-1 20199308《Linux内核原理与分析》第六周作业
  4. 如何在 Inno Setup 中执行命令行的命令
  5. Spring5参考指南: BeanWrapper和PropertyEditor
  6. 尤雨溪的vue怎么学,应该从vue-cli开始,为什么?
  7. Django入门3:视图views
  8. 什么是最好的在线UML软件工具?
  9. spark下dataframe转为rdd格式
  10. 谈谈JavaScript中的变量、指针和引用