Skip to content

Commit 8548d1f

Browse files
committed
Understanding ES6: Iterator and Generator
1 parent acf00e1 commit 8548d1f

File tree

4 files changed

+186
-5
lines changed

4 files changed

+186
-5
lines changed

.babelrc

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
{
2-
"plugins": ["transform-react-jsx"],
3-
"presets": ["es2015", "react", "stage-1"]
2+
"plugins": [
3+
"transform-react-jsx",
4+
// ["transform-runtime", {
5+
// "polyfill": false,
6+
// "regenerator": true
7+
// }]
8+
],
9+
"presets": ["es2016", "react", "stage-0"]
410
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
//**************************************************************************** */
2+
// Iterator
3+
// 迭代器只是带有特殊接口的对象。所有迭代器对象都带有 next() 方法并返回一个包含两个属性的结果对象。
4+
// 这些属性分别是 value 和 done,前者代表下一个位置的值,后者在没有更多值可供迭代的时候为 true 。
5+
// 迭代器带有一个内部指针,来指向集合中某个值的位置。当 next() 方法调用后,指针下一位置的值会被返回
6+
7+
function createIterator(items) {
8+
let i = 0;
9+
return {
10+
next: function() {
11+
let done = (i >= items.length);
12+
let value = !done ? items[i++] : undefined;
13+
14+
return {
15+
done,
16+
value
17+
}
18+
}
19+
}
20+
}
21+
22+
let iterator = createIterator([1,2,3]);
23+
// console.log(iterator.next());
24+
// console.log(iterator.next());
25+
// console.log(iterator.next());
26+
// console.log(iterator.next());
27+
28+
29+
//**************************************************************************** */
30+
// Generator
31+
// 返回迭代器的函数。生成器函数由 function 关键字和之后的星号(*)标识,同时还能使用新的 yield 关键字。
32+
// 星号的位置不能论是放在 function 关键字的后面还是在它们之间插入空格都是随意的。
33+
34+
function *createGenerator() {
35+
yield 1;
36+
yield 2;
37+
yield 3;
38+
}
39+
40+
let iterator2 = createGenerator();
41+
// console.log(iterator2.next().value);
42+
// console.log(iterator2.next().value);
43+
// console.log(iterator2.next().value);
44+
// console.log(iterator2.next().value);
45+
46+
47+
//**************************************************************************** */
48+
// Generator函数表达式
49+
// 无法使用箭头函数来创建生成器。
50+
51+
let createGenerator2 = function *(items) {
52+
for (let i = 0; i < items.length; i++) {
53+
yield items[i];
54+
}
55+
}
56+
57+
58+
59+
//**************************************************************************** */
60+
// 可迭代类型与 for-of
61+
// 可迭代类型是指那些包含 Symbol.iterator 属性的对象
62+
63+
let values = [1, 2, 3];
64+
for (let num of values) {
65+
console.log(num);
66+
}
67+
// 0, 1, 2
68+
69+
70+
// 访问默认迭代器
71+
// let iter = values[Symbol.iterator]();
72+
73+
// console.log(iter.next());
74+
75+
function isIterable(object) {
76+
return typeof object[Symbol.iterator] === 'function';
77+
}
78+
79+
80+
//**************************************************************************** */
81+
// 创建可迭代类型
82+
let collection = {
83+
items: [],
84+
*[Symbol.iterator]() {
85+
for (let item of this.items) {
86+
yield item;
87+
}
88+
}
89+
}
90+
91+
collection.items.push(1);
92+
collection.items.push(2);
93+
collection.items.push(3);
94+
95+
for (let x of collection) {
96+
console.log(x);
97+
}
98+
99+
100+
101+
//**************************************************************************** */
102+
// 生成器代理
103+
104+
function *createNumberIterator() {
105+
yield 1;
106+
yield 2;
107+
}
108+
109+
function *createColorIterator() {
110+
yield 'red';
111+
yield 'green';
112+
}
113+
114+
function *createCombinedIterator() {
115+
yield *createNumberIterator();
116+
yield *createColorIterator();
117+
yield true;
118+
}
119+
120+
const iterator3 = createCombinedIterator();
121+
console.log(iterator3.next()); // "{ value: 1, done: false }"
122+
console.log(iterator3.next()); // "{ value: 2, done: false }"
123+
console.log(iterator3.next()); // "{ value: "red", done: false }"
124+
125+
126+
127+
//**************************************************************************** */
128+
// 运行异步任务
129+
130+
function run(taskDef) {
131+
// 创建迭代器,使它们可以在别处使用
132+
let task = taskDef();
133+
134+
// 任务开始执行
135+
let result = task.next();
136+
137+
// 递归函数持续调用 next()
138+
function step() {
139+
if (!result.done) {
140+
// result = task.next();
141+
// result = task.next(result.value);
142+
143+
if (typeof result.value === 'function') {
144+
result.value((err, data) => {
145+
if (err) {
146+
result = task.throw(err);
147+
return;
148+
}
149+
150+
result = task.next(data);
151+
step();
152+
});
153+
} else {
154+
result = task.next(result.value);
155+
step();
156+
}
157+
}
158+
}
159+
160+
// 开始递归
161+
step();
162+
}
163+
164+
165+
// 例子
166+
run(function*() {
167+
console.log('start mission');
168+
yield;
169+
console.log('kill the boss');
170+
yield;
171+
console.log('mission completed');
172+
yield;
173+
})

package.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@
2222
},
2323
"homepage": "https://github.com/navono/JSPracticeSample#readme",
2424
"devDependencies": {
25+
"babel-core": "^6.26.0",
2526
"babel-eslint": "^7.2.3",
2627
"babel-plugin-transform-es2015-modules-amd": "^6.24.1",
27-
"babel-preset-stage-1": "^6.24.1",
28-
"babel-preset-stage-3": "^6.24.1",
28+
"babel-plugin-transform-runtime": "^6.23.0",
29+
"babel-preset-es2015": "^6.24.1",
30+
"babel-preset-es2016": "^6.24.1",
2931
"css-loader": "^0.28.4",
3032
"d3": "^4.9.1",
3133
"echarts": "^3.6.2",

webpack.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module.exports = {
1111
// entry: path.resolve(__dirname, './echarts/twoGrid.js'),
1212
// entry: path.resolve(__dirname, './ReactInternal/Feact.js'),
1313
// entry: path.resolve(__dirname, './echarts/dynamicData.js'),
14-
entry: path.resolve(__dirname, './basicSyntaxSample/Understanding-ES6/SetMap.js'),
14+
entry: path.resolve(__dirname, './basicSyntaxSample/Understanding-ES6/IteratorsGenerator.js'),
1515
output: {
1616
filename: '[name].js',
1717
path: path.resolve(__dirname, './build')

0 commit comments

Comments
 (0)