Promise
Promise是异步编程的一种解决方案,比传统的异步解决方案(回调函数)更强大,它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。
基本用法
ES6规定,Promise对象是一个构造函数,用来生成Promise实例。基本用法如下:
const p = new Promise((resolve, reject) => {
console.log('执行promise')
setTimeout(() => {
resolve('Hello Promise')
}, 2000)
})
p.then((res) => {
console.log('res=========', res)
})
浏览器打印输入如下:
本文重点讲述Promise和Async的区别,不展开讲Promise,有关Promise详细教程请参考:阮一峰ES6教程
Async await
ES2017标准引入了async函数,使得异步操作变的更加方便。async函数是什么?一句话,async函数是Generator函数的语法糖。要想理解async函数,就要先理解Generator函数。这里简单描述下Generator函数,不展开讲。
Generator函数
Generator函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同。下面是一个简单的generator函数
function* gen1() {
yield "hello"
yield "generator"
return "end"
}
const res = gen1()
console.log('==========', res.next())
console.log('==========', res.next())
console.log('==========', res.next())
输出如下:
调用generator函数,返回一个遍历器对象,代表generator函数的内部指针。每次调用遍历器对象的next()方法,会返回一个有value和done属性的对象。value属性表示当前的内部状态的值,是yield表达式后面的值。done表示遍历是否结束。有关generator函数讲解请看文档。
async
前面说到,async函数是generator函数的语法糖。
// generator函数
function* gen1() {
yield "hello"
yield "generator"
return "end"
}
const res1 = gen1()
console.log('=====', res1.next())
console.log('=====', res1.next())
console.log('=====', res1.next())
// async函数
async function async1() {
const aaa = await "hello"
const bbb = await "async"
console.log('aaa=======', aaa)
console.log('bbb=======', bbb)
}
async1()
输出如下:
await后一般跟异步操作,比如调用接口。上一个await执行完毕后下一个才会开始执行,因此可以像写同步代码一样写异步操作。
async函数对generator函数的改进体现在以下几点:
- generator函数执行必须要执行器,因此才有了co模块。而async函数自带执行器,执行和普通函数一样。
- 更好的语义。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。
- co模块约定,yield后面只能跟Thunk函数或者Promise对象。而await函数后面可以跟Promise对象和原始类型的值。
- async函数的返回值是Promise对象。可以使用then方法继续操作。
- yield没有返回值,await有返回值。
总结
promise和async await比较:
相同点:
- 都是异步编程解决方案
- async await是基于promise实现的,await只能在async函数中使用。
不同点:
- async await用同步的写法,可读性更强。
- async await可以使用try catch处理同步和异步错误。promise则不能使用try catch来统一处理异常。
- promise如果有多个then方法,异常捕捉比较麻烦。