1.next()、throw()、return() 的共同点

next()throw()return()这三个方法本质上是同一件事,可以放在一起理解。它们的作用都是让 Generator 函数恢复执行,并且使用不同的语句替换yield表达式。

①next()是将yield表达式替换成一个值。

const g = function* (x, y) {
let result = yield x + y;
return result;
}; const gen = g(1, 2);
gen.next(); // Object {value: 3, done: false} gen.next(1); // Object {value: 1, done: true}
// 相当于将 let result = yield x + y
// 替换成 let result = 1;

上面代码中,第二个next(1)方法就相当于将yield表达式替换成一个值1。如果next方法没有参数,就相当于替换成undefined

throw()是将yield表达式替换成一个throw语句。

gen.throw(new Error('出错了')); // Uncaught Error: 出错了
// 相当于将 let result = yield x + y
// 替换成 let result = throw(new Error('出错了'));

return()是将yield表达式替换成一个return语句。

gen.return(2); // Object {value: 2, done: true}
// 相当于将 let result = yield x + y
// 替换成 let result = return 2;

2.一个 Generator 函数里面执行另一个 Generator 函数,需要用到yield*表达式

function* foo() {
yield 'a';
yield 'b';
}

从语法角度看,如果yield表达式后面跟的是一个遍历器对象,需要在yield表达式后面加上星号,表明它返回的是一个遍历器对象。这被称为yield*表达式。


function* bar() {
yield 'x';
yield* foo();
yield 'y';
} // 等同于
function* bar() {
yield 'x';
yield 'a';
yield 'b';
yield 'y';
} // 等同于
function* bar() {
yield 'x';
for (let v of foo()) {
yield v;
}
yield 'y';
} for (let v of bar()){
console.log(v);
}
// "x"
// "a"
// "b"
// "y"

任何数据结构只要有 Iterator 接口,就可以被yield*遍历

function* gen(){
yield* ["a", "b", "c"];
} gen().next() // { value:"a", done:false } let read = (function* () {
yield 'hello';
yield* 'hello';
})(); read.next().value // "hello"
read.next().value // "h"

上面代码中,yield命令后面如果不加星号,返回的是整个数组,加了星号就表示返回的是数组的遍历器对象

上面代码中,yield表达式返回整个字符串,yield*语句返回单个字符。因为字符串具有 Iterator 接口,所以被yield*遍历

如果被代理的 Generator 函数有return语句,那么就可以向代理它的 Generator 函数返回数据

function* foo() {
yield 2;
yield 3;
return "foo";
} function* bar() {
yield 1;
var v = yield* foo();
console.log("v: " + v);
yield 4;
} var it = bar(); it.next()
// {value: 1, done: false}
it.next()
// {value: 2, done: false}
it.next()
// {value: 3, done: false}
it.next();
// "v: foo"
// {value: 4, done: false}
it.next()
// {value: undefined, done: true}

上面代码在第四次调用next方法的时候,屏幕上会有输出,这是因为函数fooreturn语句,向函数bar提供了返回值。

yield*命令可以很方便地取出嵌套数组的所有成员

function* iterTree(tree) {
if (Array.isArray(tree)) {
for(let i=0; i < tree.length; i++) {
yield* iterTree(tree[i]);
}
} else {
yield tree;
}
} const tree = [ 'a', ['b', 'c'], ['d', 'e'] ]; for(let x of iterTree(tree)) {
console.log(x);
}
// a
// b
// c
// d
// e

3.Generator 函数的this

生成一个空对象,使用call方法绑定 Generator 函数内部的this,就是将obj换成F.prototype,再将F改成构造函数,就可以对它执行new命令了,构造函数调用以后,这个F.prototype就是 Generator 函数的实例对象了

function* gen() {
this.a = 1;
yield this.b = 2;
yield this.c = 3;
} function F() {
return gen.call(gen.prototype);
} var f = new F(); f.next(); // Object {value: 2, done: false}
f.next(); // Object {value: 3, done: false}
f.next(); // Object {value: undefined, done: true} f.a // 1
f.b // 2
f.c // 3

备注:文中多数内容摘自阮一峰老师文章,仅供自我学习查阅。

ES6基础知识(Generator 函数)的更多相关文章

  1. 转: ES6异步编程:Generator 函数的含义与用法

    转: ES6异步编程:Generator 函数的含义与用法 异步编程对 JavaScript 语言太重要.JavaScript 只有一根线程,如果没有异步编程,根本没法用,非卡死不可. 以前,异步编程 ...

  2. ES6中的Generator函数

    今天小编发现一个es6中的新概念,同时也接触到了一个新关键字yeild,下面我就简单和大家聊聊es6中的generator函数.大家还可以关注我的微信公众号,蜗牛全栈. 一.函数声明:在functio ...

  3. ES6基础知识(Generator 函数应用)

    1.Ajax 是典型的异步操作,通过 Generator 函数部署 Ajax 操作,可以用同步的方式表达 function* main() { var result = yield request(& ...

  4. ES6基础知识(async 函数)

    1.async 函数是什么?一句话,它就是 Generator 函数的语法糖. const fs = require('fs'); const readFile = function (fileNam ...

  5. ES6 - Note7:Generator函数

    Generator函数 1.Generator函数是ES6增加的异步编程解决方案之一,与普通的函数行为完全不同,类似于一个状态机,内部封装了多个状态. 在函数定义的形式上,跟普通函数差不多,有两处不同 ...

  6. ES6入门之Generator函数

    Generator Generator函数是ES6提供的一种异步编程解决方案,Generator函数是一个状态机,封装了多个内部状态. 执行Generator函数会返回一个遍历器对象,也就是说,Gen ...

  7. es6基础知识

    1.超引用:(...) 用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中 function fun(...args){ console.log(args); //[1,2,3,4,5,6] ar ...

  8. php面试笔记(5)-php基础知识-自定义函数及内部函数考点

    本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 在面试中,考官往往喜欢基础扎实的面试者,而函数相关的考点 ...

  9. [C/C++基础知识] main函数的参数argc和argv

    该篇文章主要是关于C++\C语言最基础的main函数的参数知识,是学习C++或C语言都必备的知识点.不知道你是否知道该知识?希望对大家有所帮助.一.main()函数参数通常我们在写主函数时都是void ...

随机推荐

  1. PC Register简介

    PC Regiter介绍: JVM中的程序计数寄存器(Program Counter Register)中,Register的命名源于CPU的寄存器,寄存器存储指令相关的现场信息,CPU只有把数据装载 ...

  2. MySQL强人“锁”难《死磕MySQL系列 三》

    系列文章 一.原来一条select语句在MySQL是这样执行的<死磕MySQL系列 一> 二.一生挚友redo log.binlog<死磕MySQL系列 二> 前言 最近数据库 ...

  3. 微服务架构理论&SpringCloud

    一.什么是微服务? 微服务是一种程序架构模式,它提倡将单体应用程序划分成若干的小服务模块,服务之间互相协调.互相配合,为用户提供最终价值.每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制 ...

  4. Xcode相关

    Xcode相关的路径 Provisioning Profiles存放路径:~/Library/MobileDevice/Provisioning Profiles 所有模拟器(包括历史模拟器):~/L ...

  5. 【NOIP1998】 三连击 题解

    文章转载前需和原作者联系,否则追究法律责任 题目链接:https://www.luogu.com.cn/problem/P1008 首先我们来分析一下题目.要求是枚举三个数,比例为1:2:3,且各个数 ...

  6. 电脑(windows)端口被占用如何解决

    问题: 今天在启动项目的时候,控制台提示"8080端口被占用",此时我并没有启动其他项目.那么8080端口被占用解决方法如下: 1.点击左下角"开始",在搜索框 ...

  7. Java(9)数组详解

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201564.html 博客主页:https://www.cnblogs.com/testero ...

  8. TypeScript中将函数中的局部变量“导出”的方法

    首先是在模块a.js中声明一个可导出(export)的数据结构,例如: export class ModelInfo{ id: string; name:string; } 其次是在模块b中声明可导出 ...

  9. vue.$set实现原理

    上源码: export function set (target: Array<any> | Object, key: any, val: any): any { if (process. ...

  10. relativeLayout相对布局的嵌套在py中的引用

    from kivy.app import App from kivy.uix.button import Button from kivy.uix.relativelayout import Rela ...