关于Promise与async
什么是 Promise
Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。现已被 ES6 纳入进规范中。
为什么需要Promise
传统的回调函数确实可以满足回调需求,但是却有个比较大的问题,那就是回调地狱,
回调地狱是指异步函数的嵌套,总有需求是需要在回调之后再发起异步函数,比如网络请求,
那么一旦嵌套层级一多,就会导致维护困难,代码混乱
而promise能够简化代码,使用链式的方式实现,便于观察维护
function f1(){ return new Promise(resolve=>{ setTimeout(()=>{ console.log('f1'); resolve(); },1000) }) } function f2(){ return new Promise(resolve=>{ setTimeout(()=>{ console.log('f2'); resolve(); },1000) }) } f1().then(res=>{ return f2(); }).then(res=>{ return f1(); }).then(res=>{ return f2(); }).then(res=>{ setTimeout(()=>{ console.log('完成'); },1000) })
使用
let pro=function(a){ return new Promise((resolve,reject)=>{ if(a>50){ setTimeout(()=>{ resolve(a) }) }else{ reject(a) } }) } pro(55).then((res)=>{ console.log(res) return pro(60) }).then((res)=>{ console.log(res) })
常用方法
let pro=function(a){ return new Promise((resolve,reject)=>{ if(a>50){ setTimeout(()=>{ resolve(a) },2500) }else{ reject('err') } }) } let pro1=function(a){ return new Promise((resolve,reject)=>{ if(a>50){ setTimeout(()=>{ resolve(a) },1500) }else{ reject('err') } }) } Promise.all([pro(51),pro1(500)]).then((res)=>{
console.log(res)
})
//在2500毫秒后返回[51,500]
//必选在是在两个(多个)Promise都是成功之后才会执行成功,并且将返回的数据以传入的顺序传出
Promise.race([pro(51),pro1(500)]).then((res)=>{
console.log(res)
})
//在1500毫秒后返回500
//只要有一个成功就触发成功回调,并且返回成功回调的参数
解决回调地狱的其他办法
async/await可以解决
async/await是Generator的语法糖
能让异步函数以类似同步函数的方式执行,并且可以监听promise的错误
使用es5实现一下Promise
function myPromise(fun){ this.state='pending'// pending/进行中 fulfilled/成功 rejected/失败 this.execute=false this.resolveFunc=function(){} this.rejectFunc=function(){} this.then=function(fun){ this.resolveFunc=fun if(!this.execute){ this.start() } return this } this.catch=function(fun){ this.rejectFunc=fun if(!this.execute){ this.start() } return this } this.resolve=function(){ var self=this var isarr=arguments setTimeout(function() { self.resolveFunc(...isarr); self.state='fulfilled' self.execute=false }, 0); } this.reject=function(){ var self=this var isarr=arguments setTimeout(function() { self.rejectFunc(...isarr); self.state='rejected' self.execute=false }, 0); } this.start=function(){ fun(this.resolve.bind(this),this.reject.bind(this)) this.execute=true } } let bb=function(a){ return new myPromise((resole,reject)=>{ if(a>50){ setTimeout(()=>{ resole(a) },1500) }else{ reject('err') } }) } bb(51).then(res=>{ console.log(res) }).catch((res)=>{ console.log(res) })