1. iterator和iterable
iterator
是一个实现了next
方法的对象,
该next
方法返回一个{value:Anything,done:Boolean}
对象。
iterable
是一个实现了Symbol.iterator
方法的对象,
该Symbol.iterator
方法方法返回一个iterator
。
iterator = {
next: () => ({ value, done })
}
iterable = {
[Symbol.iterator]: () => iterator
}
2. generator
generator
返回的对象,既可以看做是一个iterator
,也可以看做是一个iterable
。
iterator = {
// iterator
next: v => ({ value: xxx, done: xxx }),
// iterable
[Symbol.iterator]: () => iterator
};
iterator[Symbol.iterator]() === iterator
3. yield与yield*
yield*
可以用来yield
其他iterable
,如果yield*
后面不是iterable
会报错。
yield* iterable;
4. yield表达式和yield*表达式的值
yield
表达式的值,是下一个iter.next
的参数值。
let gen = function* () {
let r = yield 1;
console.warn(r); //3
}
let iter = gen();
console.log(iter.next(2)); //{value:1,done:false}
console.log(iter.next(3)); //{value:undefined,done:true}
yield*
表达式的值,是yield*
后的iterable
在done
为true
时的value
值。
let gen1 = function* () {
//[{value:1,done:false},{value:2,done:false},{value:3,done:true}]
let r = yield* gen2();
console.warn(r); //3
}
let gen2 = function* () {
let x1 = yield 1;
let x2 = yield 2;
return 3;
}
let iter = gen1();
console.log(iter.next()); //{value:1,done:false}
console.log(iter.next()); //{value:2,done:false}
console.log(iter.next()); //{value:undefined,done:true}
5. 使用yeild*串联generator
let gen1 = function* () {
yield 1;
yield 2;
}
let gen2 = function* (next) {
yield 3;
yield* next; //yeild* iterable
yield 4;
}
let gen3 = function* (next) {
yield 5;
yield* next; //yeild* iterable
yield 6;
}
//将gen1(),gen2(...)用作iterable,将gen3(...)用作iterator
let iter = gen3(gen2(gen1()));
console.log(iter.next()); //{value:5,done:false}
console.log(iter.next()); //{value:3,done:false}
console.log(iter.next()); //{value:1,done:false}
console.log(iter.next()); //{value:2,done:false}
console.log(iter.next()); //{value:4,done:false}
console.log(iter.next()); //{value:6,done:false}
console.log(iter.next()); //{value:undefined,done:true}
console.log(iter.next()); //{value:undefined,done:true}
6. 串联任意多的generator
function compose(gens) {
return function* (next) {
if (!next) next = noop(); //next是一个iterable
let i = gens.length;
while (i--) {
//next是一个iterable
//gens[i]是一个generator,调用后返回一个iterable
//将上一个next传入gens[i],该gens[i]中就可以yield* next了
next = gens[i].call(this, next);
}
return yield* next; //yield* iterable
}
}
function* noop() { }
7. 用例
let gen = compose([gen3, gen2, gen1]);
let iter = gen();
console.log(iter.next()); //{value:5,done:false}
console.log(iter.next()); //{value:3,done:false}
console.log(iter.next()); //{value:1,done:false}
console.log(iter.next()); //{value:2,done:false}
console.log(iter.next()); //{value:4,done:false}
console.log(iter.next()); //{value:6,done:false}
console.log(iter.next()); //{value:undefined,done:true}
console.log(iter.next()); //{value:undefined,done:true}
参考
Github: koajs/compose
iterator和iterable
generator
yield与yield*
网友评论