浅谈promise的用法

promise 是es6中新增的一个对象 是异步编程的解决方案,主要解决异步编程中多个回调函数的使用问题 在实际开发过程中,我们可能遇到不止一个异步操作,每个异步操作都会有一个回调函数;那么有没有可能出现这样一种情况:本次异步操作的结果需要与下次异步操作关联起来;换一种说法就是本次异步操作当成下次异步操作的执行条件;这个当然是有可能存在的。 其实要实现上面的情况其实也很简单,那就是利用嵌套的关系;这样程序就会从最外层的代码开始执行;执行完成后才会执行内层函数;然后再执行完成后再执行最内层函数,这样一层层的直到最内层层程序执行完毕,这样就可以解决上述问题。 setTimeout(function(){ console.log('第一层'); setTimeout(function(){ console.log('第二层'); setTimeout(function(){ console.log('第三层'); },1000) },1000) },1000) 但是,如果逻辑复杂或者嵌套过多的话,很容易形成回调地狱。回调地狱是由于糟糕的编码习惯造成的,不仅会造成代码混乱,还特别容易出错。 而使用 promise 会将程序变成我们最熟悉的链式执行顺序,这样既方便书写,也能很直观的看出结果,将复杂的回调嵌套变成正常的链式调用 promise 的使用 promise 有三种状态 pending fulfilled rejected promise 有两种变化过程 pending => fulfiled(成功) pending => rejected(失败) 一旦状态发生改变,就不会再变化了 let p1 = new Promise((resolve,reject)=>{ setTimeout(resolve,3000) }) p1.then(()=>{ console.log('第一层'); }).then(()=>{ console.log('第二层'); }).then(()=>{ console.log('第三层'); }) 这样写看似没什么错误,但是最后的出的结果却是错误的,因为Promise的实例只有一个,所有状态的改变都会依赖于 p1 的改变而同时改变 。所以每当状态改变的时候,返回一个新的 Promise 实例来使状态刷新 let p1 = new Promise((resolve,reject)=>{ setTimeout(resolve,3000) }) p1.then(()=>{ console.log('第一层'); return new Promise((resolve,rejct)=>{ setTimeout(resolve,2000) }) }).then(()=>{ console.log('第二层'); return new Promise((resolve,rejct)=>{ setTimeout(resolve,1000) }) }).then(()=>{ console.log('第三层'); }) 这样就可以实现链式调用了。但是这样写还会存在问题:首先是代码量很大;其次是代码重复很多。这时候我们就自然而然的想到了封装 function timeout(time){ return new Promise((resolve,reject)=>{ setTimeout(resolve,time); }) } timeout(3000).then(()=>{ console.log('第一层'); return timeout(2000); }).then(()=>{ console.log('第二层'); return timeout(1000); }).then(()=>{ console.log('第三层'); }) promise 的其他方法 3.1 catch对应失败时候的方法,与then用法类似,对应失败时候的回调函数 3.2 all() 当所有实例都满足条件后才会去执行后面对应的函数 function timeout(time){ return new Promise((resolve,reject)=>{ setTimeout(resolve,time); }) } let p1 = timeout(5000); let p2 = timeout(3000); let p3 = timeout(1000); Promise.all([p1,p2,p3]).then(function(){ console.log("ceshi"); }) 3.3 race() 某一个实例满足条件后就会执行后面对应的函数 function timeout(time){ return new Promise((resolve,reject)=>{ setTimeout(resolve,time); }) } let p1 = timeout(5000); let p2 = timeout(3000); let p3 = timeout(1000); Promise.race([p1,p2,p3]).then(function(){ console.log("ceshi"); }) promise 与 ajax 基于promise的ajax函数封装 function ajax(url){ return new Promise(function(resolve,reject){ if(window.XMLHttpRequest){ var xhr = new XMLHttpRequest(); }else{ var xhr = new ActiveXObject("Microsoft.XMLHTTP"); } xhr.open("GET",url,true); xhr.send(); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ if(xhr.status == 200){ var data = xhr.responseText; resolve(data); } } } }) }

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):