Promise
- IE浏览器不兼容排除(EDGE):基于babel-polyfill处理兼容性(原理:自己基于Promise-->Promise A+规范 promisesaplus.com/)
- Promise是用来管理异步编程的代码,他是一种设计模式(承诺者模式),主要解决异步编程的回调地狱问题
没有promise之前是怎么请求的呢?
项目中,我们的AJAX请求都是'异步'请求的AJAX请求的并行和串行
- 串行 : 多个AJAX请求,请求之前存在于某种依赖,所以需要等上一个请求完成,才能发送下一个请求,我们把这种方式叫做串行
- 回调地狱 : 回调函数中嵌套回调函数(套娃操作)
$.ajax({
url:'xxx1.json',
method:'GET',
dataType:'JSON',
success(value){
console.log('请求成功',value);
$.ajax({
url:'xxx2.json',
method:'GET',
dataType:'JSON',
success(value){
console.log('请求成功',value);
$.ajax({
url:'xxx3.json',
method:'GET',
dataType:'JSON',
success(value){
console.log('请求成功',value);
}
})
}
})
}
})
- 并行:可以同时发送多个AJAX请求,请求和请求之间没有依赖(一般需要并发管控)
$.ajax({
url: 'xxx1.json',
success(value) {
console.log('第一个请求成功:', value);
}
});
$.ajax({
url: 'xxx2.json',
success(value) {
console.log('第二个请求成功:', value);
}
});
$.ajax({
url: 'xxx3.json',
success(value) {
console.log('第三个请求成功:', value);
}
});
初窥Promise
const query1 = () =>{
return new Promise(resolve=>
$.ajax({
url:'./data1.json',
success(value){
resolve(value);
}
})
)
}
const query2 = () =>{
return new Promise(resolve=>
$.ajax({
url:'./data2.json',
success(value){
resolve(value);
}
})
)
}
const query3 = () =>{
return new Promise(resolve=>
$.ajax({
url:'./data3.json',
success(value){
resolve(value);
}
})
)
}
基于promise解决回调地狱
query1()
.then(value=>{
console.log('第一个请求成功',value);
return query2();
})
.then(value=>{
console.log('第二个请求成功',value);
return query3();
})
.then(value=>{
console.log('第三个请求成功',value);
})
// ||async/await
(async function(){
let value = await query1();
console.log('第一个请求成功',value);
value = await query2();
console.log('第二个请求成功',value);
value = await query3();
console.log('第三个请求成功',value);
})();
new Promise([executior]);
- 必须传递一个函数,不传递函数则报错,executior执行者
- executior函数中会有两个形参:reslove & reject (reslove和reject的值都是函数)
- new Promise的时候,会把传递进来的executior函数立即执行
- 函数中一般用来管理一个异步编程代码
let p1 = new Promise(function executior(reslove,reject){
//我们管理异步编程的代码,只需要在AJAX请求成功或者失败的时候,把实例p1的状态跟着进行修改,把从服务器获取的结果或者请求失败的原因,作为实例的值即可 / 而成功干啥事情,或者失败做啥事情,全部交给THEN中的onfulfilled/onrejected来进行处理即可
$.ajax({
url:'./data1.json',
success: function(value) {
//请求成功
resolve(value)
},
error: function(value) {
//请求失败
reject(reason)
},
})
});
p1.then(
function onfulfilled(value){
console.log('成功',value);
},
function onrejected(reason){
console.log('失败',reason);
}
)
THEN链机制
- 每执行一次then方法,都会返回一个全新的Promise实例 创建promise实例的方法
- new Promise([executior])
- 实例的状态和值由executior函数执行是否报错&resolve/reject函数执行来决定
- .then(onfulfilled,onrejected),实例的状态和值和onfulfilled或者onrejected的方法执行有关系(不论那个方法执行,都是按照一下规则来影响新返回实例的状态和值)@1、看方法执行是否会报错,如果报错了,则新实例的状态是rejected,值是报错原因 @2、如果没有报错,则再看方法执行的返回值,是否为一个新的promise实例(@NEW),如果是,则@NEW的状态和值,直接决定了,THEN返回的实例的状态和值@3、如果方法返回值不是新的实例,则状态fulfilled,值是函数的返回值
- Promise.resolve([value]):直接创建一个状态是成功,值是value的实例
- Promise.reject([reason]):直接创建一个状态是失败,值是reason的实例
- Promise.all([promise,promise,...]):监听传递进来的数组中,每一个promise实例的状态,当所有实例状态是成功的时候,整体返回实例的状态也是成功,值是一个数组,包含所有实例的结果:如果其中有一个实例是失败的,整体返回的实例就是失败的,值是失败的是那个promise的值
- Promse.race:就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
//打印什么?请求成功 100 请求失败 0 请求成功 NO
let p1 = new Promise((resolve, reject) => {
resolve(100);
});
let p2 = p1.then(value => {
console.log('请求成功:', value);
return new Promise((_, reject) => {
reject(0);
});
}, reason => {
console.log('请求失败:', reason);
return new Promise((resolve) => {
resolve(100);
});
});
let p3 = p2.then(value => {
console.log('请求成功:', value);
return 'OK';
}, reason => {
console.log('请求失败:', reason);
return 'NO';
});
p3.then(value => {
console.log('请求成功:', value);
}, reason => {
console.log('请求失败:', reason);
});
THEN的"穿透/顺延"机制
- 如果onfulfilled或者onrejected没有传递,则Promise内部会自动补全
//成功态顺延 请求成功 100
new Promise(resolve =>{
resolve(100);
}).then(null/*相当于 value=>{return,value} */,reason=>{
console.log('请求失败',reason);
}).then(value=>{
console.log('请求成功',value)
})
//失败态顺延 请求失败 100
new Promise((_,reject)=>{
reject(0)
}/* reason =>{throw reason} */).then(value=>{
console.log('请求成功',value);
}/* reason =>{throw reason} */).then(value=>{
console.log('请求成功',value);
}).then(null,reason=>{
console.log('请求失败',reason);
})
Promise.prototype.cath:主要是处理状态是失败的情况(加在末尾)
- .then(null,失败态)等价于.catch(失败态)
new Promise((_,reject)=>{
reject(0)
}/* reason =>{throw reason} */).then(value=>{
console.log('请求成功',value);
}/* reason =>{throw reason} */).then(value=>{
console.log('请求成功',value);
}).catch(reason=>{
console.log('请求失败',reason);
})
Promise.all
Promse.race