美文网首页
async await 优缺点 generator 原理

async await 优缺点 generator 原理

作者: lessonSam | 来源:发表于2020-03-08 22:22 被阅读0次

    async、await 优缺点

    asyncawait 相比直接使用 Promise 来说,优势在于处理 then 的调用链,能够更清晰准确的写出代码。缺点在于滥用 await 可能会导致性能问题,因为 await 会阻塞代码,也许之后的异步代码并不依赖于前者,但仍然需要等待前者完成,导致代码失去了并发性

    下面来看一个使用 await 的代码。

    var a = 0
    var b = async () => {
      a = a + await 10
      console.log('2', a) // -> '2' 10
      a = (await 10) + a
      console.log('3', a) // -> '3' 20
    }
    b()
    a++
    console.log('1', a) // -> '1' 1
    
    
    • 首先函数b 先执行,在执行到 await 10 之前变量 a 还是 0,因为在 await 内部实现了 generatorsgenerators 会保留堆栈中东西,所以这时候 a = 0 被保存了下来
    • 因为 await 是异步操作,遇到await就会立即返回一个pending状态的Promise对象,暂时返回执行代码的控制权,使得函数外的代码得以继续执行,所以会先执行 console.log('1', a)
    • 这时候同步代码执行完毕,开始执行异步代码,将保存下来的值拿出来使用,这时候 a = 10
    • 然后后面就是常规执行代码了

    generator 原理

    GeneratorES6中新增的语法,和 Promise 一样,都可以用来异步编程

    // 使用 * 表示这是一个 Generator 函数
    // 内部可以通过 yield 暂停代码
    // 通过调用 next 恢复执行
    function* test() {
      let a = 1 + 2;
      yield 2;
      yield 3;
    }
    let b = test();
    console.log(b.next()); // >  { value: 2, done: false }
    console.log(b.next()); // >  { value: 3, done: false }
    console.log(b.next()); // >  { value: undefined, done: true }
    
    

    从以上代码可以发现,加上 *的函数执行后拥有了 next 函数,也就是说函数执行后返回了一个对象。每次调用 next 函数可以继续执行被暂停的代码。以下是 Generator 函数的简单实现

    // cb 也就是编译过的 test 函数
    function generator(cb) {
      return (function() {
        var object = {
          next: 0,
          stop: function() {}
        };
    
        return {
          next: function() {
            var ret = cb(object);
            if (ret === undefined) return { value: undefined, done: true };
            return {
              value: ret,
              done: false
            };
          }
        };
      })();
    }
    // 如果你使用 babel 编译后可以发现 test 函数变成了这样
    function test() {
      var a;
      return generator(function(_context) {
        while (1) {
          switch ((_context.prev = _context.next)) {
            // 可以发现通过 yield 将代码分割成几块
            // 每次执行 next 函数就执行一块代码
            // 并且表明下次需要执行哪块代码
            case 0:
              a = 1 + 2;
              _context.next = 4;
              return 2;
            case 4:
              _context.next = 6;
              return 3;
            // 执行完毕
            case 6:
            case "end":
              return _context.stop();
          }
        }
      });
    }
    

    相关文章

      网友评论

          本文标题:async await 优缺点 generator 原理

          本文链接:https://www.haomeiwen.com/subject/zhrsdhtx.html