一,认识Promise 相信用过JS的都知道JS是单线程的,同步的函数先执行,异步的函数先加入到一个队列中等同步执行完了再执行异步函数。基于这个JS采用异步回调的方式来处理需要等待的事件,是的代码会继续执行而不用在异步处理的地方一直等待着。同时也带来一个不好的方面,如果我们有很多的回调函数,也就是说一个回调函数里边再嵌套一个回调一层一层的嵌套,这样就很容易进入传说中的回调地狱。 注意:异步和回调不是一个东西 下面感受一下回调地狱代码的魅力:1async(1,function(value){2async(value,function(value){3async(value,function(value){4async(value,function(value){5async(value,function(value){6async(value,final);7});8});9});10});11}); 是挺有美感的但是阅读性很差,写法也让人感到无力,es6新出的promise对象已经es7的asyncawait都可以解决这个问题,但是今天的主角是Promise。 Promise是异步编程的一种解决方案,可以替代传统的解决方案回调函数和事件。ES6统一了用法,并原生提供了Promise对象。作为对象,Promise有一下两个特点:(1)对象的状态不受外界影响;(2)一旦状态改变了就不会在变,也就是说任何时候Promise都只有一种状态。Promise有三种状态,分别是:Pending(进行中),Resolved(完成),Rejected(失败)。Promise从Pending状态开始,如果成功就转到成功态,并执行resolve回调函数;如果失败就转到失败状态并执行reject回调函数。 Promise一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。二。使用Promise Promise构造函数接收一个函数作为参数,该函数的两个参数是resolve,reject,它们由JavaScript引擎提供。其中resolve函数的作用是当Promise对象转移到成功,调用resolve并将操作结果作为其参数传递出去;reject函数的作用是单Promise对象的状态变为失败时,将操作报出的错误作为其参数传递出去 介绍一下Promise的api怎么使用: 1、Promise。resolve()的作用将现有对象转为Promise对象resolved;Promise。resolve(test)newPromise(resolveresolve(test)) 2、Promise。reject()返回一个Promise对象,状态为rejected 3、Promise。prototype。then()方法接受两个参数,第一个是成功的resolved的回调,另一个是失败rejected的回调,第二个失败的回调参数可选。并且then方法里也可以返回promise对象,这样就可以链式调用了。1functionjudgeNumber(num){2varpromise1newPromise(function(resolve,reject){3num5;4if(num5){5resolve(num小于5,值为:num);6}else{7reject(num不小于5,值为:num);8}9});10returnpromise1;11}1213judgeNumber()。then(14function(message){15console。log(message);16},17function(message){18console。log(message);19}20)包含有两个方法,前一个执行resolve回调的参数,后一个执行reject回调的参数。 4、Promise。prototype。catch()发生错误的回调函数。1functionjudgeNumber(num){2varpromise1newPromise(function(resolve,reject){3num5;4if(num5){5resolve(num小于5,值为:num);6}else{7reject(num不小于5,值为:num);8}9});10returnpromise1;11}1213judgeNumber()。then(14function(message){15console。log(message);16}17)18。catch(function(message){19console。log(message);20})这个时候catch执行的是和reject一样的,也就是说如果Promise的状态变为reject时,会被catch捕捉到,不过需要特别注意的是如果前面设置了reject方法的回调函数,则catch不会捕捉到状态变为reject的情况。catch还有一点不同的是,如果在resolve或者reject发生错误的时候,会被catch捕捉到,这与java,c的错误处理时一样的,这样就能避免程序卡死在回调函数中了。 5、Promise。all()所有的事都有完成,相当于且,适合用于所有的结果都完成了才去执行then()成功的操作。1letp1newPromise(function(resolve,reject){2resolve(1);3});4letp2newPromise(function(resolve,reject){5resolve(2);6});7letp3newPromise(function(resolve,reject){8resolve(3);9});10Promise。all(〔p1,p2,p3〕)。then(function(results){11console。log(success:results);success:1,2,312})。catch(function(r){13console。log(error);14console。log(r);15}); 6、Promise。race()完成一个任务即可,相当于或。(这个经常用在一些图片比较多的网站)1模拟请求某个图片资源2functionrequestImg(){3varpnewPromise(function(resolve,reject){4varimgnewImage();5img。onloadfunction(){6resolve(img);7}8img。srcyingaxiang;9});10returnp;11}1213延时函数,用于给请求计时14functiontimeout(){15varpnewPromise(function(resolve,reject){16setTimeout(function(){17reject(图片请求超时);18},5000);19});20returnp;21}2223Promise24。race(〔requestImg(),timeout()〕)25。then(function(results){26console。log(results);27})28。catch(function(reason){29console。log(reason);30});这样就相当于requestImg方法与timeout方法的龟兔赛跑,如果五秒内图片请求成功了那么就会进入。then中,如果五秒内请求图片不成功则将进入。catch中提示请求超时PromiseAjax1functionajax(URL){2returnnewPromise(function(resolve,reject){3varreqnewXMLHttpRequest();4req。open(GET,URL,true);5req。onloadfunction(){6if(req。status200){7resolve(req。responseText);8}else{9reject(newError(req。statusText));10}11};12req。onerrorfunction(){13reject(newError(req。statusText));14};15req。send();16});17}18varURLhttps:www。cnblogs。comyingaxiang;19ajax(URL)。then(functiononFulfilled(value){20document。write(内容是:value);21})。catch(functiononRejected(error){22document。write(错误:error);23});