Generator、async 解决异步编程

Generator

生成器,生成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

yield*

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);
        }

解决异步编程的完美方案 async

因为它是使用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 () => {};
上一篇:代码生成器(使用maven插件方式生成.xml文件、实体类、dao接口)


下一篇:20210602 生成器