浅谈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);
}
}
}
})
}
发表评论 (审核通过后显示评论):