可迭代对象
typeof obj[Symbol.iterator] == 'function'
Iterator协议-迭代器模式
interface $Interator {
[Symbol.iterator](): object;
}
class IteratorObject implements $Interator {
private data = {};
private step = 0;
private keys = [];
constructor(data: object) {
this.data = data;
this.keys = Object.keys(data) as [];
}
public next() {
let result { value: undefined, done: true };
if(this.step < this.keys.length) {
result = { value: this.data[this.keys[this.step]], done: false };
this.step ++;
}
return result;
}
public [Symbol.iterator]() {
return this;
}
}
生成器
var x = 1;
function *foo() {
x++;
x = yield x++;
console.log("x:", ++x);
return x
}
let iterator = foo();
console.log(iterator.next());
console.log(iterator.next(3));
console.log(iterator.next());
- 执行foo()并没有执行生成器
*foo()
, 而只是构造了一个迭代器 - 第一个next启动了生成器, 并执行了第一行x++
*foo()
在yield语句处暂停, 并向next调用处返回{value: 2, done: false}
, 此时*foo()
处于暂停状态- 第二个next恢复生成器执行第4行, 打印出
{value: 4, done: true}
原理UML类图
具体实现
main.js
let { userFunc } = require("./userFunc")
let { generator } = require("./generator")
function main() {
let gen$ = generator(userFunc);
let iterator = gen$();
console.log(iterator.next());
}
main();
userFunc.js
function userFunc(_context) {
var str;
return function() {
while(1) {
switch((_context.pre = _context.next)) {
case 0:
_context.next = 1;
return "hello";
case 1:
str = _context.arg;
console.log(str);
_context.next = 3;
return "world";
case 3:
return _context.complete("return", "ending");
case "end":
return _context.stop();
}
}
}
}
exports.userFunc = userFunc
generator.js
let { invoker } = require("./invoker");
let { Context } = require("./context");
let { Iterator } = require("./iterator");
function generator(userFunc) {
return function() {
let context = new Context()
let generatorInvoker = invoker(userFunc, context)
return Iterator(generatorInvoker, context)
}
}
exports.generator = generator
context.js
class Context {
done = false
value = undefined
next = 0;
complete(type, result) {
if(type === "return") {
this.value = result;
this.next = "end";
}
return null;
}
stop() {
this.done = true;
return this.value
}
}
exports.Context=Context
invoker.js
function invoker(userFunc, context) {
// 状态设置为start
var state = 'start'
var userFunc$1 = userFunc(context);
return function generatorInvoker(arg) {
// 已完成
if(state === "completed") {
return { value:undefined, done: true}
}
context.arg = arg;
// 执行中
while(true) {
let result = userFunc$1() // 执行下一步,并获取状态 switch 里面return的值
// 判断是否已经执行完成
state = context.done ? "completed" : "yield";
if(result === null) {
continue
}
return {
value: result,
done: context.done
}
}
}
}
iterator.js
function Iterator(generatorInvoker, context) {
return {
next: (arg)=> {
context.method = "next";
return generatorInvoker(arg);
},
['throw']: (arg)=> {
context.method = "throw";
generatorInvoker(arg);
}
}
}
On This Page