zoukankan      html  css  js  c++  java
  • async函数

    ES2017标准引入了async函数,使得异步操作变得更加方便。

    一、含义

    什么是async函数?它就是Generator函数的语法糖

    栗子:有一个Generator函数,依次读取两个文件。

    const fs = require('fs');
    
    const readFile = function (fileName) {
      return new Promise(function (resolve, reject) {
        fs.readFile(fileName, function(error, data) {
          if (error) return reject(error);
          resolve(data);
        });
      });
    };
    
    const gen = function* () {
      const f1 = yield readFile('/etc/fstab');
      const f2 = yield readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
    };

    上面代码的函数gen可以写成async函数

    const asyncReadFile = async function () {
      const f1 = await readFile('/etc/fstab');
      const f2 = await readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
    };

    async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖。

    二、基本用法

    async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

    指定多少毫秒后输出一个值

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

    指定 50 毫秒以后,输出hello world

    async的多种使用形式

    // 函数声明
    async function foo() {}
    
    // 函数表达式
    const foo = async function () {};
    
    // 对象的方法
    let obj = { async foo() {} };
    obj.foo().then(...)
    
    // Class 的方法
    class Storage {
      constructor() {
        this.cachePromise = caches.open('avatars');
      }
    
      async getAvatar(name) {
        const cache = await this.cachePromise;
        return cache.match(`/avatars/${name}.jpg`);
      }
    }
    
    const storage = new Storage();
    storage.getAvatar('jake').then(…);
    
    // 箭头函数
    const foo = async () => {};

    返回Promise对象

    async函数返回一个 Promise 对象。

    async函数内部return语句返回的值,会成为then方法回调函数的参数。

    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(v),
      e => console.log(e)
    )
    //Error: 出错了

    Promise对象的状态变化

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

    await命令

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

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

    另一种情况是,await命令后面是一个thenable对象(即定义then方法的对象),那么await会将其等同于 Promise 对象。

    class Sleep {
      constructor(timeout) {
        this.timeout = timeout;
      }
      then(resolve, reject) {
        const startTime = Date.now();
        setTimeout(
          () => resolve(Date.now() - startTime),
          this.timeout
        );
      }
    }
    
    (async () => {
      const sleepTime = await new Sleep(1000);
      console.log(sleepTime);
    })();
    // 1000

    上面代码中,await命令后面是一个Sleep对象的实例。这个实例不是 Promise 对象,但是因为定义了then方法,await会将其视为Promise处理。

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

    错误处理

    如果await后面的异步操作出错,那么等同于async函数返回的 Promise 对象被reject

    async/await本质上基于Promise的一些封装

    setTimeout(_ => console.log(4))
        async function main(){
          console.log(1)
          await Promise.resolve()
          console.log(3)
        }
        main()
        console.log(2)
    // 1 2 3 4

    async函数在await之前的代码都是同步执行的,可以理解为await之前的代码属于new Promise时传入的代码,await之后的所有代码都是在Promise.then中的回调

    参考:https://www.cnblogs.com/jiasm/p/9482443.html

  • 相关阅读:
    Visualvm 远程测试 问题
    jsp中文件下载的实现
    MYOB 的一些开发资料
    连接MYOB ODBC,在MyEclipse 下Commit成功,在Tomcat下单独运行,Commit显示Connection 已经关闭
    也说说学习
    objectivec static变量的使用总结
    objective里面的单例模式
    对函数式编程简单理解
    个人技术生涯的感悟(2)
    苹果键盘快捷键图标
  • 原文地址:https://www.cnblogs.com/songya/p/11692739.html
Copyright © 2011-2022 走看看