生成器,生成Iterator接口对象的生成器
yield 可暂停函数,yield 后面的值可返回出去,且不终结函数进行
故generator函数一次执行可返回多个值
// Generator函数格式 (带*) function* fn2() { yield 1; yield 2; return 3; } fn(); // 不输出
修改成以下代码:
function* fn2() { yield console.log(1); yield console.log(2); return console.log(3); } let iter = fn2(); // 返回Iterator 接口对象 iter.next(); // 1 iter.next(); // 2 iter.next(); // 3
以上代码需要手动设置next,不太方便
可用for of 遍历
for 内部默认调用对象的next方法
所以通过for 遍历generator函数生成的对象,不需要手动的写next,因为next首次执行完之后,会自动调用下一次
function* fn2() { yield console.log(1); yield console.log(2); return console.log(3); } let iter = fn2(); */// 返回Iterator 接口对象 for (let key of iter) {}
function* foo(x) { var y = 2 * (yield (x + 1)); var z = yield (y / 3); return (x + y + z); } var a = foo(5); a.next(); // Object{ value: 6, done: false } a.next(); // Object{ value: NaN, done: false } // 理论应该返回 12,为什么返回NaN? // 因为上一次的yield返回给下一次next 的值默认是 undefined a.next(); // Object{ value: NaN, done: true } var b = foo(5); b.next(); // Object{ value: 6, done: false } b.next(12); // Object{ value: 8, done: false } // 输出 8??因为当next 传入12时,那么上次的yield返回的值为12,然后再*2 ,再除3 b.next(23); // Object{ value: 42, done: true } // y=24 x=5 z=13
function* f00() { yield 'a'; yield 'b'; } // Generator默认不允许在内部调用另一个Generator函数 function* bar() { yield 'x'; foo(); // // Generator默认不允许在内部调用另一个Generator函数,所以这一步无用 yield 'y'; } function* bar() { yield 'x'; yield* foo(); // 使用yield* 才使这一步有意义,指的调用一个Generator函数,而不是普通函数 yield 'y'; } for (let v of bar()) { console.log(v); }
因为它是使用Generator和Promise高度封装的
ES2017引入async(sync: 同步)
本质是 Generator函数的语法糖
这就是异步函数,跟普通函数没有什么区别
那它怎么组织代码的呢??因为它的内部有个全新的关键字 await
async function fn() { /!*await "这个操作有了结果了,才会自动继续向后执行";*!/ // 相当于 yield ,但是yield启动的时候必须手动 next // 之所以是Generator的语法糖,就是因为 将yield 换成await 的时候,会自动next const res1 = await "异步1"; const res2 = await "异步2"; }
异步操作返回值出来,如果setTimeout 返回的结果要让 res 接收到,要用Promise
async function fn() { // 异步操作返回值出来,如果setTimeout 返回的结果要让 res 接收到,要用Promise /*const res = await setTimeout();*/ const res = await new Promise(resolve => { setTimeout(() => { console.log("异步操作完成"); resolve("异步1要返回的数据"); }, 100); }) console.log(res); } fn();
// 表达式写法 const fn = async function() {}; // 箭头函数 const fnn = async () => {};