本篇博文出至于个人
github
仓库:web-study,若是你以为对你有帮助欢迎star,大家的点赞是我持续更新的动力,谢谢!javascript
异步编程在前端开发中尤其常见,从最先的XHR
,到后来的各类封装ajax
,再到DOM
事件触发的回调,无不涉及异步编程。今天我们来聊聊ES6
中新提出的异步解决方案:Promise
和async/await
。前端
Promise 是一种对异步操做的封装,能够经过独立的接口添加在异步操做执行成功、失败时执行的方法。主流的规范是 Promises/A+。java
Promise中有几个状态:node
* pending: 初始状态, 非 fulfilled 或 rejected; * fulfilled: 成功的操做,为表述方便,fulfilled 使用 resolved 代替; * rejected: 失败的操做。
pending能够转化为fulfilled或rejected而且只能转化一次,也就是说若是pending转化到fulfilled状态,那么就不能再转化到rejected。而且fulfilled和rejected状态只能由pending转化而来,二者之间不能互相转换。git
Promise是一个构造函数,本身身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等一样很眼熟的方法。github
resolve
的用法web
var p = new Promise(function(resolve, reject){ //作一些异步操做 setTimeout(function(){ resolve('随便什么数据'); }, 2000); }) p.then(res => { console.log(res) // '随便什么数据' })
Promise的构造函数接收一个参数,是函数,而且传入两个参数:resolve,reject,分别表示异步操做执行成功后的回调函数和异步操做执行失败后的回调函数。其实这里用“成功”和“失败”来描述并不许确,按照标准来说,resolve是将Promise的状态置为fullfiled,reject是将Promise的状态置为rejected。ajax
在上面的代码中,咱们执行了一个异步操做,也就是setTimeout
,2秒后,而且调用resolve方法,表示异步操做执行成功。编程
reject
的用法javascript var p = new Promise(function(resolve, reject){ //作一些异步操做 setTimeout(function(){ reject('随便什么数据'); }, 2000); }) p.catch(err => { console.log(err) // '随便什么数据' })
promise
上面咱们在异步操做中调用了reject
方法,也就是说把Promise的状态由pending
转换到了fulfilled
状态,最后能够经过Promise实例对象的catch()
方法获取异步数据。
异步操做是 JavaScript 编程的麻烦事,不少人认为async函数是异步操做的终极解决方案。
async/await是写异步代码的新方式,优于回调函数和Promise。
async/await是基于Promise实现的,它不能用于普通的回调函数。
async/await与Promise同样,是非阻塞的。
async/await使得异步代码看起来像同步代码,再也没有回调函数。可是改变不了JS单线程、异步的本质。
使用await,函数必须用async标识
await后面跟的是一个Promise实例或者是其余的任意js表达式(意义不大)
var fun = async () => { let result = await Promise.resolve(123) console.log(result) } fun() // 123
await
等待的虽然是promise对象,可是不用调用.then()方法就能直接获得返回值。
Promise
虽然一方面解决了callback
的回调地狱,可是相对的把回调“纵向发展”了,造成了一个回调链。example:
function sleep(wait) { return new Promise((res,rej) => { setTimeout(() => { res(wait) },wait) }) } /* let p1 = sleep(100) let p2 = sleep(200) let p =*/ sleep(100).then(result => { return sleep(result + 100) }).then(result02 => { return sleep(result02 + 100) }).then(result03 => { console.log(result03) })
控制台输出:
300
后面的结果都是依赖前面的结果。
改为async/await写法就是:
async function demo() { let result01 = await sleep(100) //上一个await执行以后才会执行下一句 let result02 = await sleep(result01 + 100) let result03 = await sleep(result02 + 100) // console.log(result03); return result03 } demo().then(result => { console.log(result) })
由于async返回的也是promise对象,因此用then接受就好了。
结果:
300
须要注意的就是 await
是强制把异步变成了同步,这一句代码执行完,才会执行下一句。