写法不同 ES5 正常写法
Promise
1 get(url).then((res)=>{})
async_await
1 2 3 (async ()=>{ let res = await get(url) })()
总结:
ES5 写法和 promise 写法,主要区别在写法的不同,可以让回调函数,划分出去在.then 的函数里去执行,使得代码更加的另外,也可以将两个不同的参数,可以划分开来写。
async 和 promise 的区别,不要在于 async 时 promise 的语法糖,这种形式的写法在底层编译之后会自动转化成 promise 的写法
Promise 实现原理 promise 需要实现的功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 function fn(resolve,reject){ setTimeout(()=>{ if(true){ resolve() }else{ reject() } }) } var p1 = new LcPromise(fn) p1.then(function(res){ document.body.style.background = "greenyellow" console.log("这是成功做的事情") console.log(res) }) p1.catch(function(res){ document.body.style.background = "pink" console.log("这是失败做的事情") console.log(res) })
p1promise 对象发送了异步操作,必然会有 1 个未来事件,在未来要执行。这个过程由传入的函数对象 fn 执行。函数 fn 里必然需要由成功执行和失败执行的函数
1 创建类构造对象
1 2 3 4 5 6 7 8 9 10 11 12 class LcPromise{ constructor(fn) { //将成功的事件函数集成在successList数组里 this.successList = []; //这里将所有的失败函数集成到failList里 this.failList = [] //pending,fullfilled,rejected this.state = "pending" //传入的函数对象,(异步操作的函数内容) fn(this.resolveFn.bind(this),this.rejectFn.bind(this)) } }
构造函数的作用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class LcPromise{ constructor(fn) { //将成功的事件函数集成在successList数组里 this.successList = []; //这里将所有的失败函数集成到failList里 this.failList = [] //pending,fullfilled,rejected this.state = "pending" //传入的函数对象,(异步操作的函数内容) fn(this.resolveFn.bind(this),this.rejectFn.bind(this)) } then(successFn,failFn){ if(typeof successFn=='function'){ this.successList.push(successFn) } if(typeof failFn=='function'){ this.failList.push(failFn) } } catch(failFn){ if(typeof failFn=='function'){ this.failList.push(failFn) } } }
作用:
定义调用成功和失败的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 //promise aysnc await proxy Iteratror class LcPromise{ constructor(fn) { //将成功的事件函数集成在successList数组里 this.successList = []; //这里将所有的失败函数集成到failList里 this.failList = [] //pending,fullfilled,rejected this.state = "pending" //传入的函数对象,(异步操作的函数内容) fn(this.resolveFn.bind(this),this.rejectFn.bind(this)) } then(successFn,failFn){ if(typeof successFn=='function'){ this.successList.push(successFn) } if(typeof failFn=='function'){ this.failList.push(failFn) } } catch(failFn){ if(typeof failFn=='function'){ this.failList.push(failFn) } } resolveFn(res){ this.state = "fullfilled" this.successList.forEach(function(item,index){ //将成功的事件循环调用 item(res) }) } rejectFn(res){ this.state = 'rejected' //注册到的失败所有事件进行调用 this.failList.forEach(function(item,index){ item(res) }) throw Error(res); } }
作用:
成功时调用成功数组里所有的函数,失败时调用失败数组里所有的函数。
应用 如何将 promise 与 async 和 await 结合使用
典型异步读写的回调操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 fs.readFile(path,{flag:'r',encoding:"utf-8"},function(err,data){ if(err){ //console.log(err) //失败执行的内容 reject(err) }else{ //console.log(data) //成功执行的内容 resolve(data) } //console.log(456) })
转换成 promise 对象
1 2 3 4 5 6 7 8 9 new Promise(function(resolve,reject){ fs.readFile(path,{flag:'r',encoding:"utf-8"},function(err,data){ if(err){ reject(err) }else{ resolve(data) } }) })
由于每次使用,都不想写这么多代码,那么就会把这样的写法直接进行函数的封装
1 2 3 4 5 6 7 8 9 10 11 12 function fsRead(path){ return new Promise(function(resolve,reject){ fs.readFile(path,{flag:'r',encoding:"utf-8"},function(err,data){ if(err){ reject(err) }else{ resolve(data) } }) }) }
使用的时候,就可以使用 promise 写法
1 2 3 4 p1 = fsRead(path) //就可以得到promise对象 p1.then(function(data){ console.log('输出数据:',data) })
asycn_await 写法
1 2 3 (async ()=>{ let data = await fsRead(path) })()
异步 async 函数调用之后也是一个 promise 对象
1 2 3 4 5 6 7 8 9 10 11 12 13 (async ()=>{ async function test(){ let data = await fsRead(path) return data; } let p = test()//异步函数调用后,也是一个promise对象 p.then(function(data){ console.log(data) }) let a = await test()//异步函数调用后,也是一个promise对象 console.log(123) })()