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

LearnPromiseDiary

时间:2023-03-27 12:33:53 JavaScript

LearnPromiseDiaryWhatisPromise?promise(译:承诺;期望;期约),在《javascript高级程序设计》本书中称为“期约”,“期约”的解释是这样的结果还不存在,我的理解是:Iamlookingforwardtoouragreement结果(我真的很期待和她有个好结果,比如结婚,生娃,幸福一辈子,哈哈哈).可世事难料,她可能会拒绝丑,嘿嘿,你别想太多,不管结果如何,自己都得正确面对这些结果。其实我还蛮爱玩的。我和这个约会后,我和另一个女孩约会,我约会后另一个女孩和另一个帅哥约会...Promise是ECMAScript6提供的一个类,目的是为了更优雅地编写复杂的代码的异步任务。Promise状态机Promise状态机有三种状态:pending(待定)、fulfilled(完成或reloved)、rejected(拒绝)=(resolve,reject)=>reject()functionpromise_instance(callback){returnnewPromise(callback)}console.log(promise_intanc(callback_pending));//回调函数没有执行resolve或reject,状态为pending状态console.log(promise_intanc(callback_resolve));//回调函数执行resolve,状态为resloved状态console.log(promise_intanc(callback_reject));//回调函数执行reject,状态为rejected(拒绝)状态Promisethen(),catch(),.prototype方法中的finally(),作为Promise在rejection或fulfillment状态Promise的handler.resolve()Promise不必一开始就处于pending状态,然后转为resloved(重设),Rejected。通过Promise.resolve()这个静态方法,可以将任意值转化为一个resolvedPromise//下面两行p1和p2的打印结果是一样的letp1=newPromise((resolve,reject)=>resolve(1))letp2=Promise.resolve(1)console.log(p1)//Promise{:1}console.log(p2)//Promise{:1}如果这个方法通过in参数是一个Promise,那么它的行为就类似于一个空包,最终的值就是传入参数的值,可以说是一个幂等函数letp=Promise.resolve(1)console.log(p===Promise.resolve(p));//true根据上面的文章,这个幂等函数会保留传入的Promise的状态letp=newPromise(()=>{})console.log(Promise.resolve(p));//Promise{}console.log(p);////Promise{}它可以包装任何非Promise值,包括错误对象letp=Promise。resolve(newError('error'))console.log(p);//Promise{:Error:errorPromise.reject()类似于Promise.resolve(),Promise.reject()可以将任意值转换为拒绝状态的Promise,并抛出一个异步错误,但是这个错误不能被try/catch捕获,它只能被Promise的.then()或.catch()方法捕获。但是它不像Promise.resolve()是一个幂等方法,即使传入Promise.reject(),它返回一个拒绝原因为Promise.reject()Promise.reject('err').then(null,(err)=>console.log(err))//errPromise.reject('err').catch((err)=>console.log(err))//errtry{Promise.reject('err')}catch(err){//无法捕获,catch没有执行,因为它没有通过异步方式捕获console.log(err);}Promise.prototype.then()Promise.prototype.then()是一个Promise实例添加handler的主要方法,.then()可以接收两个参数,分别是resolved状态下的回调函数和resolved状态下的回调函数被拒绝的状态。//resolve先执行newPromise((resolve,reject)=>{resolve('我给你兑现')//先执行,转为resolve状态reject('我拒绝你')//如果resolve先执行,不会执行,会被默默忽略,因为状态只能改变一次}).then((res)=>console.log(res),//res获取resolve传过来的参数,output:thisiscashExecuted(rej)=>console.log(rej),//这里不执行)//reject先执行newPromise((resolve,reject)=>{reject('我拒绝你')//先执行,转为reject状态resolve('I'llcashitoutforyou')//如果先执行reject,则不会执行,会被静默忽略,因为状态只能改变一次}).then((res)=>console.log(res),//这里不执行(rej)=>console.log(rej),//rej获取reject传过来的参数,输出:thisisrefusedexecution)Promise.prototype.catch()承诺。prototype.catch()是.then(null,()=>{}}的语法糖,newPromise((resolve,reject)=>{reject('Irejectyou')})用于捕获拒绝原因。catch(err=>console.log(err))//我拒绝你Promise.prototype.finally()Promise.prototype.finally()就是Promise无论转换成什么状态都会执行,它无法知道Promise处于什么状态。后面的finally()包的内容,除了pending状态或者抛出错误,都会返回Promise或者Promise,其余的都会返回Promisepending状态,无论什么时候resolve或者reject,就会在resolve或returnPromiseletp2=p1.finally(()=>newPromise(()=>setTimeout(()=>resolve('bar'),100)));setTimeout(console.log(p),0);//PromisesetTimeout(()=>setTimeout(console.log(p2),200));//最后一个setTimeou100ms执行回调后到达setTimeout回调,p2此时得到的已经resolve,输出:Promise:fooPromise和同步代码执行顺序Promise在状态改变后不会立即执行,它的handler会被压入消息队列。所以同步过程执行完之后,它的handler就会被执行。letp=letPromise.resolve();p.then(()=>console.log('Promise'));console.log('同步输出')//它的输出顺序是:先输出同步输出,再输出输出PromisePromise链式调用Promise可以链式调用,因为then(),catch(),finally()会返回一个新的Promise如果真正了解Promise状态处理机制,下面代码的执行结果就可以了如指掌。letp=newPromise((resolve,reject)=>{resolve('resolve')}).then(res=>console.log(res))//resolve.then(res=>console.log(res))//undefined.then(res=>console.log(res))//undefined.then(()=>Promise.reject('reject')).catch(e=>{console.log(e);return8//相当于returnPromise.resolve(8)})//reject.then((res)=>{console.log(res);returnError('error')//相当于returnPromise.reject('error')抛出异步错误}).then(res=>console.log(res),//不执行err=>console.log(err)//输出错误).finally(f=>console.log(f))//最后肯定会执行,f不会得到任何值,输出undefinedPromise.all()Promise.all()的参数是一个数组,只有当数组的所有Promise都被resolved的时候。Then(),否则执行.catch()Promise.all([Promise.resolve(1),Promise.resolve(2),newPromise((resolve,reject)=>resolve(3))]).then(result=>console.log(result))//[1,2,3]//第一个被拒绝的handler的Promise.rece([Promise.resolve(1),Promise.reject(2),Promise.reject(3)),新舞会ise((resolve,reject)=>resolve(3))]).then(result=>console.log(result))//不执行.catch(e=>console.log(e))//得到第一个被拒绝的值,输出:2Promise.race()Promise.race()的参数也是一个数组,会返回第一个状态最先改变的Promise//resolve(100)先执行Promise.race([newPromise((resolve,reject)=>setTimeout(()=>resolve(300),300)),newPromise((resolve,reject)=>setTimeout(()=>resolve(200),200)),newPromise((resolve,reject)=>setTimeout(()=>resolve(100),100)),]).then(result=>console.log(result))//100.catch(e=>console.log(e))//不执行//Reject(100)先执行Promise.race([newPromise((resolve,reject)=>setTimeout(()=>resolve(300),300)),newPromise((resolve,reject)=>setTimeout(()=>resolve(200),200)),newPromise((resolve,reject)=>setTimeout(()=>reject(100),100)),]).then(result=>console.log(result))//不执行.catch(e=>console.log(e))//100合成Promise链式调用Promise.then()+Array.reduce()可以将多层链式调用简化为一个通用的函数compose,让代码更加简洁functionadd2(x){return(x+2)};functionadd3(x){return(x+3)}functionadd4(x){return(x+4)}functioncompose(...args){返回x=>args.reduce((promise,fn)=>promise.then(fn),Promise.resolve(x))}Promise扩展Promise进度通知类TrackablePromiseextendsPromise{constructor(executor){constnotifyHandlers=[];super((res,rej)=>{returnexecutor(res,rej,(status)=>{notifyHandlers.map((handlder)=>handler(status));})})这个。notifyHandlers=notifyHandlers;}notify(notifyHandler){this.notifyHandlers.push(notifyHandler);返回这个}}letp=newTrackablePromise((res,rej,notify)=>{functioncountdown(x){if(x>0){notify(`${20*x}%remaining`);setTimeout(()=>countdown(x-1),1000)}else{res();}}countdown(5);})p.notify((x)=>setTimeout(console.log,0,'progress',x));p.then(()=>setTimeout(console.log,0,'completed'));/*(1秒后打印):progress80%remaining(2Printinseconds):progress60%remaining(3秒内打印):剩余进度40%(4秒内打印):剩余进度20%(5秒后打印):完成*/