js 迭代器协议、生成器

Iterator Helpers: 一些类似数组的方法,但是是惰性计算的

// 异步编程的语法目标,就是怎样让它更像同步编程。
// 协程(Coroutine)允许执行被挂起与被恢复,更适合于用来实现彼此熟悉的程序组件,如合作式多任务迭代器无限列表管道
// 例子:整个流程无锁,由一个线程执行,produce 和 consumer 协作完成任务,所以称为"协程",而非线程的抢占式多任务。
// 子程序(函数调用)就是协程的一种特例

一个迭代器协议对象会有一个名为 next 的方法(yield后立即暂停), 调用该方法后会返回一个拥有两个属性的对象, 一个是 value 属性, 值可以是任意值, 以及一个 done 属性, 布尔值, 表示该对象是否已经被迭代完毕.
遵循了这个协议的对象都可以称之为迭代器(协议)对象.
Generator.prototype.throw() // 用来向生成器抛出异常,可以在生成器中使用 try..catch 进行捕获(包含所有 yield)

生成器是一种可以从中退出并在之后重新进入的函数。
生成器的环境(绑定的变量)会在每次执行后被保存,下次进入时可继续使用。
// 写成看似(yield)同步的代码却能异步执行
// 相当于把所有回调函数全部写在一起了
// 就是提供一种编程方式

调用一个生成器函数并不马上执行它的主体,而是返回一个这个生成器函数的迭代器(iterator)协议对象。当这个对象的next()方法被调用时,生成器函数的主体会被执行直至第一个yield表达式,该表达式定义了迭代器协议对象返回的值,或者;能被 yield*委派至另一个生成器函数。

next(value) 方法接收一个参数,赋值给 YieldExpress // 跟yield 返回值无关
// 可以用function.send来接收这个参数

function* 声明和构造函数 GeneratorFunction 返回一个生成器对象(迭代协议的对象)

Iterable 接口是可迭代对象(可以获得迭代器【如数组: [][Symbol.iterator]()】的对象)所需的接口。例如,for (let e of C) 中的 C 必须实现 Iterable 接口。可迭代对象必须提供 Symbol.iterator (表示为 @@iterator)方法,该方法会返回一个迭代器
obj[Symbol.iterator] = function() { return iterObj;
// Class 中使用 * [Symbol.iterator]() {}

///////////////////////////////////////////// 用迭代器协议 写的 js 睡眠函数 sleep;
function sleep(ms){
return function(callback){
setTimeout(callback, ms);
};
}
function* gf(){
console.log('1');
yield sleep(1000);
console.log('2');
};
function co(gf) {
let g = gf();
let i = () => {
let v = g.next();
if (!v.done) v.value(i); // 保证next中yield 返回的值是一个接受回调函数(回调即next)的函数
}
i();
}
co(gf);