• async函数


    async函数

    基本概念

    async 函数是什么?一句话,它就是 Generator 函数的语法糖。

    将上一章的代码改成 async 函数的版本:

    const { promisify } = require("util");
    const path = require('path')
    const file1 = path.join(__dirname, './text/1.txt')
    const file2 = path.join(__dirname, './text/2.txt')
    const readFileP = promisify(readFile)
    
    function* f() {
      let data1 = yield readFileP(file1)
      console.log('耶,完成了1,数据是' + data1);
      let data2 = yield readFileP(file2)
      console.log('耶,完成了2,数据是' + data2);
    }
    
    //async函数的版本
    async function f() {
      let data1 = await readFileP(file1)
      console.log('耶,完成了1,数据是' + data1);
      let data2 = await readFileP(file2)
      console.log('耶,完成了2,数据是' + data2);
    }
    
    

    比较后就会发现,async函数的版本就是将 Generator 函数的星号(*)替换成async,将yield替换成await

    定义async函数

    使用async关键字定义一个async函数:

    async function f() {
      let data1 = await readFileP(file1)
      console.log('耶,完成了1,数据是' + data1);
      let data2 = await readFileP(file2)
      console.log('耶,完成了2,数据是' + data2);
    }
    

    执行async函数

    执行async函数则相当于执行了一个自动运行的Generator函数,async函数如果返回的结果不是Promise,则会运行结果包装成一个Promise返回:

    async function f() {
      console.log(1);
    }
    f().then(()=>{
      console.log(2);
    })
    
    async function f() {
      console.log(1);
      return 'done'
    }
    
    f().then(value => {
      console.log(value);
    })
    

    await关键字

    yield类似,async函数中可以使用await关键字,await关键字后面一般会写一个Promise实例,async函数执行的过程中,每次遇到await关键字,会将控制权转回外部环境

    1. 如果await后面是Promise实例,则会等到该 Promise实例被resolve后,才会把本次await到下次await之间的代码推到MircoTask(微任务)中等待执行,并且await的返回值是该Promise实例resolve的值
    2. 如果await后面不是Promise实例,则会立即将本次await到下次await之间的代码推到MircoTask(微任务)中等待执行,并且await的返回值是等于await后面表达式的值:
    async function f() {
      let data = await new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('a')
        }, 2000)
      })
      console.log(data);
    }
    
    //f()
    //console.log('end')
    

    如果await后面不是Promise 实例

    async function f() {
      let data = await 'a'
      console.log(data);
    }
    f()
    console.log('end'); 
    //end
    //a
    

    async函数的错误处理

    如果Promise被reject或抛出错误,await之后的代码不会执行,因此,需要使用try..catchawait进行错误捕捉:

    async function f() {
      try {
        let data = await new Promise((resolve, reject) => {
          setTimeout(() => {
            reject('123')
          }, 2000)
        })
        //后续代码无法执行
        console.log('done');
      }catch (e) {
        console.log('发生错误:',e);
      }
    }
    f()
    

    async函数处理并发异步任务

    如果,async函数中的每个await都是等到前面await resolve后才会执行,如果想并发执行,可以使用Promise.all:

    /*并发处理异步*/
    async function f() {
      let time1 = new Date()
      let [data1,data2] = await Promise.all([
        new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve('123')
          }, 2000)
        }),
        new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve('123')
          }, 3000)
        })
      ])
      console.log(data1,data2,'用时:'+ (new Date() - time1));
    }
    f()
    

    async函数与Promise的对比

    async函数写异步逻辑相比Promise会更加简洁,在处理不同异步结果相互依赖,错误处理,if...else分支等情况时更加简便:

    const {readFile} = require('fs')
    const { promisify } = require("util");
    const path = require('path')
    const file1 = path.join(__dirname, './text/1.txt')
    const file2 = path.join(__dirname, './text/2.txt')
    const file3 = path.join(__dirname, './text/3.txt')
    const readFileP = promisify(readFile)
    
    function f1() {
      readFileP(file1).then(data1 =>{
        console.log('耶,完成了1,数据是' + data1);
        return readFileP(file2)
      }).then(data2 => {
        console.log('耶,完成了1,数据是' + data2);
        return readFileP(file3)
      }).then(data3 => {
        console.log('耶,完成了1,数据是' + data3);
      })
    }
    
    async function f2() {
      let data1 = await readFileP(file1)
      console.log('耶,完成了1,数据是' + data1);
      let data2 = await readFileP(file2)
      console.log('耶,完成了2,数据是' + data1 + data2);
      let data3 = await readFileP(file3)
      console.log('耶,完成了2,数据是' + data1 + data2 + data3);
    
    }
    f()
    
  • 相关阅读:
    WPF入门教程系列六——布局介绍与Canvas(一)
    WPF入门教程系列五——Window 介绍
    WPF入门教程系列四——Dispatcher介绍
    WPF入门教程系列三——Application介绍(续)
    html5 标签
    html5
    sublime汉化教程
    html5 文本格式化
    主键和索引的区别
    响应式布局的开发基础知识
  • 原文地址:https://www.cnblogs.com/xm0328/p/14128001.html
Copyright © 2020-2023  润新知