Generator
- 概念: Generator 函数返回的遍历器对象
-
基本用法
// 定义生成器函数 function* g() { yield "a"; yield "b"; yield "c"; return "ending"; } // 返回Generator对象 console.log(g()); // g {<suspended>} console.log(g().toString()); // [object Generator]
-
每次
next
执行一次yield
, 并返回{value: "a", done: false}
function* g() { yield "a"; yield "b"; yield "c"; return "ending"; } var gen = g(); // console.log(gen.next()); // {value: "a", done: false} // console.log(gen.next()); // {value: "b", done: false} // console.log(gen.next()); // {value: "c", done: false} // console.log(gen.next()); // {value: "ending", done: true} // 没有return时, 最后也会打印`{value: undefined, done: false}` // next方法代替上面手动next() function next() { let { value, done } = gen.next(); console.log(value); // 依次打印输出 a b c end if (!done) next(); // 直到全部完成 } next();
-
传参问题
function* say(foo) { let a = yield foo; console.log(a); let b = yield "2"; console.log(b); } let it = say("bar"); // 返回迭代器 // a的值并非yield返回值,而是下次next参数 // 此次执行, 只到yield, 没有到赋值a console.log(it.next()); // 输出 { value: 'bar', done: false } // 第二次的next(参数), 才会赋值到a console.log(it.next("我是被传进来的1")); // 输出'我是被传进来的1' // 输出{ value: '2', done: false } console.log(it.next("我是被传进来的2")); // 输出'我是被传进来的2' // 输出{ value: undefined, done: true }
-
搭配promise, 处理异步(异步一的回调当参数传给异步二)
// 使用Generator顺序执行两次异步操作 function* r(num) { // 此次yield返回 {value: promise, done: false } const r1 = yield compute(num); yield compute(r1); } // compute为异步操作,结合Promise使用可以轻松实现异步操作队列 function compute(num) { return new Promise(resolve => { setTimeout(() => { const ret = num * num; console.log(ret); // 输出处理结果 resolve(ret); // 操作成功 }, 1000); }); } // 不使用递归函数调用 let it = r(2); // {value: promise,done:false} // it.next().value.then(num => it.next(num)); // 修改为可处理Promise的next function next(data) { let { value, done } = it.next(data); // 启动 if (!done) { value.then(num => { next(num); }); } } next();
-
async-await
- 区别: 是generator的一种特殊形式的语法糖, 并没有完全实现generator异步流程的控制