当前位置: 首页 > Web前端 > JavaScript

手工实现promise源码

时间:2023-03-26 20:31:32 JavaScript

promise是一个解决回调地狱问题的异步方案。Promise在语法上是一个构造函数。在功能上,它封装了异步操作,可以获取到它的运行结果。1.基本用法constp=newPromise((resolve,reject)=>{setTimeout(()=>{//异步操作resolve(value)},100)})构造函数Promise的参数是一个执行函数,executor函数的参数分别为resolve和reject:第一个回调函数在Promise对象的状态变为resolved时调用,第二个回调函数在Promise对象的状态变为rejected时调用2.Promise的实现constructorPromise对象内部有三种状态。初始值为pending,resolved成功,rejected。被拒绝对象的内部状态在执行过程中只能改变一次,不可逆。初始化开始时,status的状态为pendingcallbacks保存成功和失败的回调函数self.status=PENDINGself.data=undefinedself.callbacks=[]//每个元素结构{onResolved(){}onRejected(){}}functionPromise(excutor){constself=thisself.status=PENDINGself.data=undefinedself.callbacks=[]//每个元素结构{onResolved(){}onRejected(){}}functionresolve(value){//resolve函数的作用是将promise状态变为resolvedif(self.status!==PENDING){//如果不是pending,直接return}self.status=RESOLVEDself.data=值if(self.callbacks.length>0){setTimeout(()=>{self.callbacks.forEach(callbacksObj=>{callbacksObj.onResolved(value)});},0);}}functionreject(reason){if(self.status!==PENDING){return}self.status=REJECTEDself.data=reasonif(self.callbacks.length>0){setTimeout(()=>{//遍历回调队列self.callbacks.forEach(callbacksObj=>{callbacksObj.onRejected(原因)});});}}//立即同步执行extry{excutor(resolve,reject)}catch(err){reject(err)}}3.thenpromise实例then方法first第一个参数是resolved状态的回调函数,第二个参数是被拒绝状态的回调函数,这两个参数都是可选的并且返回的也是一个Promise对象。有三种情况。如果回调函数返回一个promise是一个promisereturn,那么promise的结果就是这个promise的结果。如果回调函数返回一个不是promisereturn的promise,它就会成功。值是返回值。失败原因是错误Promise.prototype.then=function(onResolved,onRejected){constself=thisonResolved=typeofonResolved==='function'?onResolved:value=>valueonRejected=typeofonRejected==='函数'?onRejected:reason=>{throwreason}//返回一个新的promise对象returnnewPromise((resolve,reject)=>{//根据执行结果函数句柄调用指定的回调函数处理并改变returnpromise状态(callback){try{constresult=callback(self.data)if(resultinstanceofPromise){//如果回调函数返回的promise是promisereturn,则promise的结果就是promiseresult的结果。then(value=>{resolve(value)},reason=>{reject(reason)})//result.then(resolve,reject)}else{//如果回调函数返回的promise不是promisereturn,则成功。value是返回值resolve(result)}}catch(error){//如果抛出异常,return的promise会是Willfailresaoniserrorreject(error)}}if(self.status===PENDING){self.callbacks.push({onResolved(){handle(onResolved)},onRejected(){handle(onRejected)}})}elseif(self.status===RESOLVED){setTimeout(()=>{handle(onResolved)})}else{setTimeout(()=>{handle(onResolved)})}})}4.Promise对象的catch方法用于捕获错误回调方法Promise.prototype.catch=function(onRejected){returnthis.then(undefined,onRejected)}5Promise的resolve方法是将对象变成Promise对象。如果resolve方法的参数是非Promise对象,则直接传值。如果是Promise对象,取值的结果就是Promise的结果Promise.resolve=function(value){returnnewPromise((resolve,reject)=>{//value是promiseif(valueinstanceofPromise){//使用value的结果作为promise的结果value.then(resolve,reject)}else{//value不是promiseresolve(value)}})}6.Promise的reject方法返回一个被拒绝的Promise对象Promise.reject=function(reason){returnnewPromise((resolve,reject)=>{reject(reason)})}7.Promise的all方法功能:执行多个Promise,返回一个新的Promise实例。all方法接受一个数组参数:如果所有的Promise对象都成功了,会返回一个数组来保存每一个成功的Promise返回值。如果一个Promise对象失败了,那么新的Promise就会失败。返回值是失败的Promise的返回值。Promise.all=function(promises){//用来保存所有成功值的数组。length)//用来保存成功的promise个数letcount=0returnnewPromise((resolve,reject)=>{//获取每个promise的结果promises.forEach((p,index)=>{Promise.resolve(p).then(value=>{count++values[index]=value//保存成功的值//如果全部成功,则将返回的promise转为成功if(count===promises.length){resolve(values)}},reason=>{reject(reason)})})})}8.Promise的race方法函数:返回一个新的Promise对象,最先执行完成的Promise的返回值作为新Promise对象的结果Promise.race=function(promises){returnnewPromise((resolve,reject)=>{//获取每个承诺的结果promises.forEach((p)=>{Promise.resolve(p).then(value=>{resolve(value)},reason=>{reject(reason)})})})}