promise是ES6新增的异步编程解决方案 为了解决回调函数嵌套过多的问题 避免形成回调地狱
promise的异步是微任务
js代码的执行顺序 同步程序–promise微任务–异步程序
promise在执行时有三种状态 pending resolve(fullfilled)rejected
对应着两种状态变化 这两种状态变化由异步操作的结果决定
一旦状态发生改变 就不再变化
var p = new Promise(function(resolve,reject){
setTimeout(function(){
resolve(10); //这个参数10是给回调函数传递的数据
},500)
})
p.then(function(data){ //成功时的回调
console.log(data);
return new Promise(function(resolve,reject){
setTimeout(resolve,2000);
})
},function(){console.log("aa")}) //失败时的回调
.then(function(){
console.log('bb');
return new Promise(function(resolve,reject){
setTimeout(resolve,2000);
})
}).then(function(){
console.log('cc');
})
两个方法
var p1 = new Promise(function(resolve,reject){
setTimeout(resolve,2000);
});
var p2 = new Promise(function(resolve,reject){
setTimeout(resolve,3000);
});
var p3 = new Promise(function(resolve,reject){
setTimeout(resolve,5000);
});
//all() 三个实例状态都发生改变 在执行then 以a时间最长的为准
//race() 三个实例状态有一个发生改变 就执行then 以时间最短的那个为准
Promise.all([p1,p2,p3]).then(()=>{
console.log('aa');
})
Promise.race([p1,p2,p3]).then(()=>{
console.log('bb');
})
个人总结
在使用promise的时候可以与ajax组合使用 利用封装好的Ajax函数 在原有的基础上改造 返回一个promise实例 并且本应该由ajax的success回调函数接受的下载数据 可以放到resolve的参数里面 在then的回调函数里去进行处理 如下所示
function ajax(url){
return new Promise((resolve,reject)=>{
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() :new ActiveXObject('Microsoft.XMLHTTP');
xhr.open("get",url);
xhr.send();
xhr.onreadystatechange=()=>{
if(xhr.readyState==4){
if(xhr.status==200){
var data = xhr.responseText;
console.log(data);
resolve(data);
}
}
}
});
}
var p = new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('get', 'url');
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
resolve(xhr.responseText);
}
setInterval(function () {
reject(new Error('连接超时'));
}, 2000)
}
});
p.then(function (data) {
console.log(data)
}).catch(function (err) {
if (err) throw err;
}).finally(function () {
console.log('asdf')
})