• async与await


    Generator 函数的语法糖。有更好的语义、更好的适用性、返回值是 Promise

    • await 和 promise 一样,更多的是考笔试题,当然偶尔也会问到和 promise 的一些区别。
    • await 相比直接使用 Promise 来说,优势在于处理 then 的调用链,能够更清晰准确的写出代码。缺点在于滥用 await 可能会导致性能问题,因为 await 会阻塞代码,也许之后的异步代码并不依赖于前者,但仍然需要等待前者完成,导致代码失去了并发性,此时更应该使用 Promise.all。
    • 一个函数如果加上 async ,那么该函数就会返回一个 Promise
    • async => *
    • await => yield
    // 基本用法
    
    async function timeout (ms) {
      await new Promise((resolve) => {
        setTimeout(resolve, ms)    
      })
    }
    async function asyncConsole (value, ms) {
      await timeout(ms)
      console.log(value)
    }
    asyncConsole('hello async and await', 1000)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

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

    优缺点:

    async/await的优势在于处理 then 的调用链,能够更清晰准确的写出代码,并且也能优雅地解决回调地狱问题。当然也存在一些缺点,因为 await 将异步代码改造成了同步代码,如果多个异步代码没有依赖性却使用了 await 会导致性能上的降低。

    async原理

    async/await语法糖就是使用Generator函数+自动执行器来运作的

    // 定义了一个promise,用来模拟异步请求,作用是传入参数++
    function getNum(num){
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(num+1)
            }, 1000)
        })
    }
    
    //自动执行器,如果一个Generator函数没有执行完,则递归调用
    function asyncFun(func){
      var gen = func();
    
      function next(data){
        var result = gen.next(data);
        if (result.done) return result.value;
        result.value.then(function(data){
          next(data);
        });
      }
    
      next();
    }
    
    // 所需要执行的Generator函数,内部的数据在执行完成一步的promise之后,再调用下一步
    var func = function* (){
      var f1 = yield getNum(1);
      var f2 = yield getNum(f1);
      console.log(f2) ;
    };
    asyncFun(func);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 在执行的过程中,判断一个函数的promise是否完成,如果已经完成,将结果传入下一个函数,继续重复此步骤
    • 每一个 next() 方法返回值的 value 属性为一个 Promise 对象,所以我们为其添加 then 方法, 在 then 方法里面接着运行 next 方法挪移遍历器指针,直到 Generator函数运行完成

  • 相关阅读:
    UG NX二次开发(C++)-创建样条曲线(二)-UF_MODL_create_spline使用
    用VS Code运行C语言(安装VS Code,mingw的下载和安装)
    Android kotlin实现Viewpager滑动背景透明效果渐变
    Process finished with exit code -1073740791 (0xC0000409)
    学习笔记-ThinkPHP5之任意方法调用RCE(六)
    想把MP3音频转换成OGG格式需要什么工具?四种你不知道的音频转换工具在这里
    大黄酸偶联鸡卵白蛋白 rhein-OVA,BFNB/MEB/MEA/BFNH-OVA
    Docker postgres
    猿创征文 | 使用插槽解决组件内容传递问题(1)
    排序算法:堆排序
  • 原文地址:https://blog.csdn.net/php_martin/article/details/125856789