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

    什么是async函数?

    Generator的语法糖,让异步操作变得更加方便

    const asyncFunc = async funtion(){
      const f1 = await readFile('./a.txt')
      const f2 = await readFile('./b.txt')
      console.log(f1.toString())  
      console.log(f2.toString())    
    }

    相比于Generator的改进

    1. Generator的执行必须依靠执行器,这也就造成了co模块的出现。而async函数中自带执行器,调用时只需要一行--asyncFunc()。而Generator需要首先获得遍历器,再执行next()或者使用co模块,才能真正调用
    2. Generator的yield后只能跟Promise对象或Thunk函数,而async函数的await后可以跟Promise对象和原始类型的数据(会自动转成立即执行resolved的Promise)
    3. 返回值是Promise对象,可以直接对其进行.then调用。而Generator返回iterator接口,很麻烦。

    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('jack').then();
    
            // 箭头函数
            const foo = async () => {};

    返回Promise对象

    async funtion foo(){
      return 'hello'  
    }
    foo().then(resolved => console.log(resolved))
    // hello

    当抛出异常时,导致返回的Promise对象状态变为rejected,错误对象会被rejected处理函数捕获

    async function foo() {
                throw new Error('出错了')
            }
            foo().then(
                v => console.log(v),
                e => {console.log(e)}
                )

    Promise对象的状态变化

    当async函数中存在多个await语句时,会等到所有await一个个执行完,才会改变状态,执行.then(除非遇到错误异常或return语句)

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

    以上代码中,只有等到fetch请求结束、获取响应文本结束、匹配结束,才会改变promise状态,执行.then

    await命令

    通常情况下,await命令后跟一个promise对象,返回该对象的结果。如果不是,就返回对应的值

    还有一种情况,await后是一个定义then的方法,也会被当做是promise对象处理

    当await后面的promise状态变为rejected时,就会被catch捕捉。只要某个await后的promise状态变为rejected,后面的await不会继续执行

    async function foo() {
                    await Promise.reject('出错了') // ‘出错了’
                    await Promise.resolve('hello world') // 不会执行
            }
    
            foo()
            .then(v=>{
                console.log(v)
            })
            .catch(e=>{
                console.log(e)
            })

    如果想要前一个异步操作失败不影响后面异步操作的执行,可以通过以下两种方式

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

    顶层await

    通常情况下await命令只能在async函数中使用,而为了达到模块异步加载问题,目前有一个语法提案,允许在async函数外部写await。

    当加载某个模块时,如果其中包含异步操作,加载方无法确定被加载模块是否执行结束。因此在导出对象时添加await,直到异步操作完成才能被其他模块导入。

    const dynamic = import(someMission);
    const data = fetch(url);
    export const output = someProcess((await dynamic).default, await data);

    使用注意

    1. 因为await后面跟着的promise对象,只要reject就会执行catch代码,中止继续执行。因此最好将所有await放在try..catch...代码块中
    2. await只能在async函数中使用,否则报错
    3. 如果有多个await,且后面的异步操作不存在继发关系,最好同时触发
      1.   
        async function foo(){
          await Promise.all([getfoo(), getimg()])  
        }
  • 相关阅读:
    docker stats
    Appium 环境搭建
    docker 进入容器
    Mac下Mysql启动异常["ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)"]
    python 虚拟环境--virtualenv
    visjs 绘图 图标 动态添加数据
    js 滑块登录验证
    js iframe 最顶层显示
    转化为数组
    videojs双击全屏幕观看,videojs动态加载视频
  • 原文地址:https://www.cnblogs.com/ashen1999/p/12719840.html
Copyright © 2011-2022 走看看