您现在的位置是:首页 > 正文

学习ES6(十):Promise的语法糖await和async

2024-01-30 23:32:56阅读 0

一、await和async

在ES2017中,引入了async函数,来方便异步操作。

特点

  1. async/await从上到下顺序执行。
  2. async/await可以传递的参数数量不受限制。参数被作为普通局部变量处理,可使用let或者const关键字定义的块级变量。
  3. 同步代码和异步代码可以一起编写,只是要注意异步过程需要包装成一个Promise对象并置于await关键字后面
  4. async/await是对Promise的改进,准确来说是语法糖,本质上还是Promise。

二、使用方法

使用async定义异步处理函数

    async function testAsync(){
        return "hello async"
    }
    console.log(testAsync())
    //Promise { 'hello async' }
    testAsync().then(r=>{
        console.log(r)
    })

我们直接用async关键字定义函数。我们把整个函数执行后的结果打印出来,它直接返回一个Promise对象,可以简便之前定义promise对象的写法,既然返回的是Promise对象,那么就可以直接使用then方法进行下一步操作。这就是被称为语法糖的原因。

而且不仅可以使用then方法,还可以在最后使用捕捉错误的catch方法。

    async function testAsync(){
        return "hello async"
    }
    console.log(testAsync())
    //Promise { 'hello async' }
    testAsync().then(r=>{
    //打印出 hello async
        console.log(r)
        //抛出错误
        throw new Error("this is a mistake")
    }).catch(err=>{
    //捕捉到错误
		console.log(err)
	})

async配合Promise使用

执行下列代码:

function testAsync(){
        return "hello async"
    }
function testPromise(){
        return new Promise((resolve)=>{
            setTimeout(() => {
                resolve("hello Promise")
            }, 3000);
            //resolve("hello Promise")
        })
}
    //await 函数比如放在 async函数里面,await会等待 promise函数执行后resolve后的结果
async function test(){
        var Async_1 = await testAsync()
        var Promise_1 = await testPromise().then()
        console.log(Async_1)
        console.log(Promise_1)
}
test()

运行之后,效果是隔了三秒钟,同时打印。 你可以尝试把setTimeout注释掉,然后把注释的部分取消注释运行。发现也是同时打印

这是为什么呢??

因为await指令如果放在async函数里面,那么该指令会暂停当前异步函数的执行,并等待promise执行,,然后再执行异步函数,并返回结果。如果等待的不是promise对象,则返回该值本身

所以这里的代码执行顺序应该是:

  • test()执行
  • 暂停test()
  • 执行await testAsync
  • 执行 await testPromise().then()
  • 执行test()

因为里面有await关键字,所以要暂停async function test()的执行。等待函数体里面的Promise执行结束后才继续执行。

三、总结

async 和 promise 的写法对比

async function func(){
	return 'hello world'
}
console.log(func())
let p = new Promise((resolve,reject)=>{
	resolve('hello world')
})
console.log(p)

这样写,虽然最后的打印的结果是一样的。但是第二个代码Promise对象的状态已经从pending 变成 fulfilled了,如果在then中抛出一个错误的话,也不会经过错误捕捉操作。从一开始就要决定状态, 然后根据状态去选择执行下一步。使用promise对象,如果第一步没有完成状态的选择,那么不会去执行then中的方法。
如果使用async的话,如果你在then中不抛出错误的话,它会默认按照fulfilled状态一直执行then中的方法,不会固定为fulfilled状态。只要你某个then方法中抛出错误,那么就直接跳过执行catch方法。
所以相比之下还是 async要更方便一点。
这是我下面实验的代码:

    async function func(){
        return 'hello world'
    }
    console.log(func().then(r=>{
        console.log(r)
    }).then(r=>{
        console.log("1")
    }).then(r=>{
        console.log("2")
        throw new Error("这是错误")
    }).then(r=>{
        console.log("3")
    }).catch(err=>{
        console.log(err)
    }))
    let p = new Promise((resolve,reject)=>{
        console.log('1')
        //一开始就要指定状态,如果不使用resolve,那么只会输出1,使用了resolve之后,输出 1 2,即使抛出错误,也无法处理。
        resolve()
        // throw new Error("错误")
    }).then(r=>{
        console.log("2")
    }).catch(err=>{
        // console.log(err)
    })
    console.log(p)

网站文章

  • 深入理解python当中的函数

    深入理解python当中的函数

    作为一个Python的初学者来说,深入理解Python中函数的概念是一件重要的事情。 重点1:如何理解函数是第一类对象(一等公民) 函数是第一类对象的概念: 第一:函数的名字是对函数的引用 第二:函数作为第一类对象可以赋值给其他的变量 第三:可以作为函数的参数传递给其他的函数 第四:可以作为函数的返回值 第五:函数可以作为容器类型的一个元素 简单来说,在python当中,函数可...

    2024-01-30 23:32:48
  • MySQl语句中的union ,order by 、group by 、having、where等的用法

    union union 和 union all 联合 union 保证两张表的列 相同 union 可以连接两张表的查询结果 去掉重复的数据 union all 不能去掉重复的数据 having 如果...

    2024-01-30 23:32:20
  • spring配置文件标签中使用${}占位符获得配置文件的属性值

    spring配置文件标签中使用${}占位符获得配置文件的属性值

    一般情况下我们在spring的配置文件中使用标签是这样的,,但是最近项目中使用到其他工程的依赖jar包,在自己的spring配置文件中需要这样写 其中env的值是从eoa_config.properties里面获取。 如果是以上这种写法,在启动时spring报错,无法解析env,原因很简单,在import动作时在属性文件加载之前。 没办法只能翻spring源码

    2024-01-30 23:32:12
  • Java-类的五大成员

    Java学习笔记类的五大成员。

    2024-01-30 23:32:04
  • 服务器安装node,配置vue环境

    服务器安装node,配置vue环境

    1.node下载包链接:https://pan.baidu.com/s/1fCDwL3dSOsGeIMOn0q3lsA提取码:thk62.node官网CNPM Binaries Mirror下载.gz...

    2024-01-30 23:31:58
  • c++中set与map用法详解

    关于STL c++ STL之所以得到广泛赞誉,也被很多人使用,不只是提供了向vector,string,list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和常用的数据结构操作。vect...

    2024-01-30 23:31:25
  • JavaScript - 判断字符串中是否包含特殊字符与空格(正则表达式)

    我们在验证一个字符串是否为空或包含特殊字符时,可使用本文提供的正则表达式,省去很多校验代码。如下正则表达式,可保证字符串的合法性。

    2024-01-30 23:31:17
  • Linux signal()和kill()

    Linux signal()和kill()

    编写程序:用 fork( )创建两个子进程,再用系统调用 signal( )让父进程捕捉键盘上来的中断信号(即按^c 键);捕捉到中断信号后,父进程用系统调用 kill( )向两个子进程发出信号,子进...

    2024-01-30 23:30:47
  • 一步一步学Silverlight 2系列(32):图形图像综合实例—“功夫之王”剧照播放...

    版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://terrylee.blog.51cto.com/342737/68194 ...

    2024-01-30 23:30:40
  • 如何使用js来编写vue组件?

    如何使用js写vue组件?3分钟看懂,简单示例代码。完整代码。可复制直接进行运行

    2024-01-30 23:30:33