Skip to content

Commit bada09e

Browse files
committed
增加generator的示例代码
1 parent b3866ad commit bada09e

File tree

13 files changed

+1357
-118
lines changed

13 files changed

+1357
-118
lines changed

.babelrc

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"plugins": ["transform-react-jsx"]
2+
"plugins": ["transform-react-jsx"],
3+
"presets": ["es2015"]
34
}

.eslintrc.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ module.exports = {
77
"react"
88
],
99
"env": {
10-
"browser": true,
11-
"es6": true,
12-
// "commonjs": true,
13-
// "jquery": true
10+
"browser": true,
11+
"es6": true,
12+
// "commonjs": true,
13+
// "jquery": true
14+
},
15+
"ecmaFeatures": {
16+
"modules": true
1417
},
1518
"rules": {
1619
//关闭额外的分号检查

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
/node_modules
1+
/node_modules
2+
/lib

.vscode/tasks.json

+8-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// "args": ["Hello world!"],
99
"showOutput": "always",
1010

11-
"args": ["Yo!"],
11+
// "args": ["Yo!"],
1212
"echoCommand": true,
1313
"suppressTaskName": true,
1414
"tasks": [
@@ -29,6 +29,13 @@
2929
"Good Bye"
3030
],
3131
"suppressTaskName": false
32+
},
33+
{
34+
"taskName": "zz",
35+
"command": "babel",
36+
"args": [
37+
"../basicSyntaxSample/generator.js"
38+
]
3239
}
3340
]
3441
}

basicSyntaxSample/generator.js

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
* @Author: Ping Qixing
3+
* @Date: 2017-06-18 10:52:17
4+
* @Last Modified by: Ping Qixing
5+
* @Last Modified time: 2017-06-18 15:25:16
6+
* @Description
7+
*/
8+
// import { thunkify } from 'thunkify';
9+
10+
function * helloworldGenerator () {
11+
yield 'hello';
12+
yield 'world';
13+
return 'ending';
14+
}
15+
// 调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象
16+
// 下一步,必须调用遍历器对象的next方法,使得指针移向下一个状态。也就是说,每次调用next方法,
17+
// 内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。
18+
// 换言之,Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。
19+
20+
let hw = helloworldGenerator();
21+
22+
// for (let i of hw) {
23+
// console.log(i);
24+
// }
25+
26+
console.log(hw.next());
27+
28+
let arr = [1, [[2, 3], 4], [5, 6]];
29+
30+
let flat = function * (a) {
31+
let length = a.length;
32+
for (let i = 0; i < length; i++) {
33+
let item = a[i];
34+
if (typeof item !== 'number') {
35+
yield * flat(item);
36+
} else {
37+
yield item;
38+
}
39+
}
40+
};
41+
42+
for (var f of flat(arr)) {
43+
console.log(f);
44+
}
45+
46+
// yield表达式本身没有返回值,或者说总是返回undefined
47+
// 由于next方法的参数表示上一个yield表达式的返回值,所以第一次使用next方法时,不能带有参数
48+
function * foo (x) {
49+
var y = 2 * (yield (x + 1));
50+
var z = yield (y / 3);
51+
return (x + y + z);
52+
}
53+
54+
var a = foo(5);
55+
a.next() // Object{value:6, done:false}
56+
a.next() // Object{value:NaN, done:false}
57+
a.next() // Object{value:NaN, done:true}
58+
59+
var b = foo(5);
60+
b.next() // { value:6, done:false }
61+
b.next(12) // { value:8, done:false }
62+
b.next(13) // { value:42, done:true }
63+
64+
// 一旦next方法的返回对象的done属性为true,for...of循环就会中止,且不包含该返回对象
65+
66+
// 原生的 JavaScript 对象没有遍历接口,无法使用for...of循环,通过 Generator 函数为它加上这个接口,就可以用了。
67+
function * objectEntries (obj) {
68+
let propKeys = Reflect.ownKeys(obj);
69+
70+
for (let propKey of propKeys) {
71+
yield [propKey, obj[propKey]];
72+
}
73+
}
74+
75+
let jane = { first: 'Jane', last: 'Doe' };
76+
77+
// for (let [key, value] of objectEntries(jane)) {
78+
// console.log(`${key}: ${value}`);
79+
// }
80+
81+
// another implemention
82+
function * objectEntries2 () {
83+
let propKeys = Object.keys(this);
84+
85+
for (let propKey of propKeys) {
86+
yield [propKey, this[propKey]];
87+
}
88+
}
89+
90+
jane[Symbol.iterator] = objectEntries2;
91+
for (let [key, value] of jane) {
92+
console.log(`${key}: ${value}`);
93+
}
94+
95+
// Generator与状态机
96+
// ES5
97+
let ticking = true;
98+
let clock = function () {
99+
if (ticking) {
100+
console.log('Tick!');
101+
} else {
102+
console.log('Tock!');
103+
}
104+
ticking = !ticking;
105+
}
106+
107+
// ES6
108+
let clock2 = function * () {
109+
while (true) {
110+
console.log('Tick!');
111+
yield;
112+
console.log('Tock!');
113+
yield;
114+
}
115+
};
116+
117+
// Thunk函数, 实际中可以使用thunkify模块
118+
const Thunk = function (fn) {
119+
return function (...args) {
120+
return function (callback) {
121+
return fn.call(this, ...args, callback);
122+
}
123+
}
124+
}
125+
126+
// 比如这样使用
127+
// let readFileThunk = Thunk(fs.readFile);
128+
// readFileThunk(fileA)(callback);
129+
130+
function faz (a, cb) {
131+
cb(a);
132+
}
133+
134+
const fazt = Thunk(faz);
135+
fazt(1)(console.log);
136+
137+
// let thunkify = require('thunkify');
138+
139+
// const ft = thunkify(faz);
140+
// ft(2)(console.log);

basicSyntaxSample/iterator.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @Author: Ping Qixing
33
* @Date: 2017-06-18 08:54:33
44
* @Last Modified by: Ping Qixing
5-
* @Last Modified time: 2017-06-18 10:49:02
5+
* @Last Modified time: 2017-06-18 10:49:43
66
* @Description
77
*/
88

@@ -93,4 +93,5 @@ let objGenerator = {
9393
// 一个数据结构只要部署了Symbol.iterator属性,就被视为具有iterator接口,就可以用for...of循环遍历它的成员。
9494
// 也就是说,for...of循环内部调用的是数据结构的Symbol.iterator方法。
9595

96-
// for...of循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、后文的 Generator 对象,以及字符串。
96+
// for...of循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、
97+
// 后文的 Generator 对象,以及字符串。

index.html

+4-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ <h1>This is a Demo</h1>
1010
<div id="output"></div>
1111
</div>
1212
</body>
13-
<script>
13+
<!--<script src="node_modules/requirejs/require.js"></script>-->
14+
<script src="./basicSyntaxSample/generator.js">
1415
</script>
15-
<script src="./basicSyntaxSample/iterator.js">
16+
<!--<script src="./lib/generator.js" />-->
1617

17-
</script>
18+
1819
</html>

0 commit comments

Comments
 (0)