前言

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的效果。

js es6深入应用系列(Generator)的更多相关文章

  1. es6 快速入门 系列 —— 变量声明:let和const

    其他章节请看: es6 快速入门 系列 变量声明:let和const 试图解决的问题 经典的 var 声明让人迷惑 function demo1(v){ if(v){ var color='red' ...

  2. 【2015上半年总结】js开源组件开发系列索引

    js开源组件开发系列一索引 2015.8 by 田想兵 个人网站 从3月份进入新公司以来,时经五个月,我以平均每周1个小组件的速度,已经完成的js组件有22个之余了,已基本上全部用到实际项目中,这些小 ...

  3. 在Node.js中使用RabbitMQ系列二 任务队列

    在上一篇文章在Node.js中使用RabbitMQ系列一 Hello world我有使用一个任务队列,不过当时的场景是将消息发送给一个消费者,本篇文章我将讨论有多个消费者的场景. 其实,任务队列最核心 ...

  4. js es6 map 与 原生对象区别

    区别 object和Map存储的都是键值对组合.但是: object的键的类型是 字符串: map的键的类型是 可以是任意类型: 另外注意,object获取键值使用Object.keys(返回数组): ...

  5. Node.js笔记07——不使用generator自定义一个项目,深入了解项目结构

    一.初始化项目 新建项目 git init manager 新建view文件夹,建几个静态文件夹 新建app.js 快速初始化项目依赖 npm init -y 安装express npm instal ...

  6. js 深入原理讲解系列-Promise

    js 深入原理讲解系列-Promise 能看懂这一题你就掌握了 js Promise 的核心原理 不要专业的术语,说人话,讲明白! Q: 输出下面 console.log 的正确的顺序? const ...

  7. js 深入原理讲解系列-事件循环

    js 深入原理讲解系列-事件循环 能看懂这一题你就掌握了 js 事件循环的核心原理 不要专业的术语,说人话,讲明白! Q: 输出下面 console.log 的正确的顺序? console.log(' ...

  8. js 深入原理讲解系列-currying function

    js 深入原理讲解系列-currying function 能看懂这一题你就掌握了 js 科里函数的核心原理 不要专业的术语,说人话,讲明白! Q: 实现 sum 函数使得以下表达式的值正确 cons ...

  9. es6 快速入门 系列 —— promise

    其他章节请看: es6 快速入门 系列 Promise Promise 是一种异步编程的选择 初步认识Promise 用 Promise 来实现这样一个功能:发送一个 ajax,返回后输出 json ...

随机推荐

  1. 数据源管理 | PostgreSQL环境整合,JSON类型应用

    本文源码:GitHub·点这里 || GitEE·点这里 一.PostgreSQL简介 1.和MySQL的比较 PostgreSQL是一个功能强大的且开源关系型数据库系统,在网上PostgreSQL和 ...

  2. python 携程asyncio实现高并发示例1

    import asyncio #携程(携程不是函数) async def print_hello(): while True: print("hello world") await ...

  3. python中文语料分词处理,按字或者词cut_sentence

    cut_sentence.py import string import jieba import jieba.posseg as psg import logging #关闭jieba日制 jieb ...

  4. Solr搜索结果高级设置

    一.选择响应格式 XML是Solr的默认响应格式.从Solr的角度看,什么样的响应格式并不重要.Solr可以返回XML.JSON.Ruby.Python.PHP.二进制Java等,甚至是自定义格式.使 ...

  5. Ubuntu 搜索文件

    1.whereis 文件名 特点:快速,但是是模糊查找 例如: whereis php #会把php,php.ini,php.*所在的目录都找出来. 2.find / -name 文件名 特点:准确, ...

  6. Node 接入阿里云实现短信验证码

    本文介绍在案例云开通短信服务的流程以及在Node项目中使用的方法. 一.开通阿里云短信服务 登陆阿里云,然后进入 https://dysms.console.aliyun.com/dysms.htm  ...

  7. MATLAB 之MATLAB2016b 安装破解教程

    MATLAB2016b 安装破解教程 安装包: 链接: https://pan.baidu.com/s/1RNwRGRjR-bHQEq1OMJ57OA 提取码: r663 步骤: (1)R2016b_ ...

  8. Java阻塞队列四组API介绍

    Java阻塞队列四组API介绍 通过前面几篇文章的学习,我们已经知道了Java中的队列分为阻塞队列和非阻塞队列以及常用的七个阻塞队列.如下图: 本文来源:凯哥Java(kaigejava)讲解Java ...

  9. c语言-----劫持自己02

    在上一节 c语言-----劫持原理01 已经叙述了劫持原理,下边正式进入劫持实战 1. 需要实现的功能 在c语言中 system("notepad") 可以打开一个记事本 syst ...

  10. JAVA进程CPU高的解决方法

    无限循环的while会导致CPU使用率飙升吗?经常使用Young GC会导致CPU占用率飙升吗?具有大量线程的应用程序的CPU使用率是否较高?CPU使用率高的应用程序的线程数是多少?处于BLOCKED ...