• ES6 async function


    ES2017 标准引入了 async 函数,使得异步操作变得更加方便,由于async函数返回的是Promise对象,可以作为await命令的参数。

    async function timeout(ms) {
      await new Promise((resolve) => {
        setTimeout(resolve, ms);
      });
    }
    
    async function asyncPrint(value, ms) {
      await timeout(ms);
      console.log(value);
    }
    
    asyncPrint('hello world', 50);

    返回 Promise 对象

    async function f() {
      return 'hello world';
    }
    
    f().then(v => console.log(v))
    // "hello world"

    async函数内部抛出错误,会导致返回的 Promise 对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到

    async function f() {
      throw new Error('出错了');
    }
    
    f().then(
      v => console.log('resolve', v),
      e => console.log('reject', e)
    )
    //reject Error: 出错了

    Promise 对象的状态变化

    async函数返回的 Promise 对象,必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。

    async function getTitle(url) {
      let response = await fetch(url);
      let html = await response.text();
      return html.match(/<title>([sS]+)</title>/i)[1];
    }
    getTitle('http://localhost:8080/').then(console.log(123))

    await 命令

    正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。

    async function f() {
      // 等同于
      // return 123;
      return await 123;
    }
    
    f().then(v => console.log(v))
    // 123

    任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。

    async function f() {
      await Promise.reject('出错了');
      await Promise.resolve('hello world'); // 不会执行
    }

    如果希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个await放在try...catch结构里面,这样不管这个异步操作是否成功,第二个await都会执行。

    async function f() {
      try {
        await Promise.reject('出错了');
      } catch(e) {
      }
      return await Promise.resolve('hello world');
    }
    
    f()
    .then(v => console.log(v))
    // hello world

    async 函数的实现原理

    将 Generator 函数和自动执行器,包装在一个函数里

    async function fn(args) {
      // ...
    }
    
    // 等同于
    
    function fn(args) {
      return spawn(function* () {
        // ...
      });
    }
    
    function spawn(genF) {
      return new Promise(function(resolve, reject) {
        const gen = genF();
        function step(nextF) {
          let next;
          try {
            next = nextF();
          } catch(e) {
            return reject(e);
          }
          if(next.done) {
            return resolve(next.value);
          }
          Promise.resolve(next.value).then(function(v) {
            step(function() { return gen.next(v); });
          }, function(e) {
            step(function() { return gen.throw(e); });
          });
        }
        step(function() { return gen.next(undefined); });
      });
    }
  • 相关阅读:
    Anaconda(4.8.3)(Anaconda3-2020.02-Windows-x86_64)安装日志和启动问题排查日志
    abp学习日志九(总结)
    abp学习日志八(多租户)
    abp学习日志六(模块化开发)
    abp学习日志七(动态API)
    abp学习日志五(领域服务)
    abp学习日志四(仓储)
    ug主菜单men文件按书写格式,这样写有利单个dll调用
    NX开发,blockUI窗口调用blockUI窗口
    VS2013快捷键大全
  • 原文地址:https://www.cnblogs.com/magicg/p/13841915.html
Copyright © 2020-2023  润新知