目录
promise的链式调用(例题和我自己对于promise的理解)
promise A+ 规定:
1.所有的异步场景,都可以看作是一个异步任务,每个异步任务,在JS中应该表现为一个对象,该对象称之为promise对象,也叫做任务对象
2.每个任务对象,都应该有两个阶段,三个状态(执行后只能是完成或失败一种状态)
未决阶段(unsettled) 已决阶段(settled)
挂起状态(pending) --> 完成状态(fulfilled)
或 失败状态(rejected)
根据常理,它们之间存在以下逻辑
1.任务总是从未决阶段变到已决阶段,无法逆行
2.任务总是从挂起状态编导完成或失败状态,无法逆行
3.时间不能倒流,历史不可改写,任务一旦完成或失败,状态就固定下来,永远无法改变
3.挂起->完成,称之为resolve;挂起->失败,称之为reject。任务完成时,可能有一个相关数据;任务失败时,可能有一个失败原因
未决阶段(unsettled) 已决阶段(settled)
挂起状态(pending) --resolve(data)--> 完成状态(fulfilled)+ data
--reject(reason)--> 失败状态(rejected)+ data
4.可以针对任务进行后续处理,针对完成状态的后续处理称之为onFulfilled,针对失败的后续处理称之为onRejected
未决阶段(unsettled) 已决阶段(settled)
挂起状态(pending) --resolve(data)--> 完成状态(fulfilled)+ data --> data+onFulfilled
--reject(reason)--> 失败状态(rejected)+ data --> reason+onRejected
———————————————————————————————————————————
例:
const pro = new Promise((resolve,reject)=>{ //挂载两个函数,成功与失败
console.log("开始百米短跑");
const duration = Math.floor(Math.random()*5000);
setTimeout(()=>{
if(Math.random()<0.5){
resolve(duration); //成功的话
}
else{
reject("脚扭伤了"); //失败的话
}
}, duration);
});
pro.then(
(data)=>{
console.log("跑完了"); //成功的话执行这里
},(reason)=>{
console.log("没跑完"); //失败的话执行这里
}
)
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//或
function a(){
return new Promise((。。。,。。。)=>{。。。})
}
a.then(()=>{},()=>{})
注意点:
new Promise((resolve,reject)=>{
resolve(1);
resolve(2);//这句是无效代码
reject(3);//这句也同样无效,因为只判断一次状态
})
catch方法
.catch(onRejected) = .then(null,onRejected) --->
当必失败时,可以使用catch,相当于没有完成态的then
promise的链式调用(例题和我自己对于promise的理解)
Promise --> then(判断) --> Promise --> then(判断) --> Promise
1. then方法必定会返回一个新的Promise
可理解为后续处理也是一个任务
2. 新任务的状态取决于后续处理:
1.若没有相关的后续处理,新任务的状态和前任务一致,数据为前任务的数据
2.若有后续处理但未执行,新任务挂起。
3.若后续处理执行了,则根据后续处理的情况决定新任务的状态
1.后续处理执行无错,新任务的状态为完成,数据为后续处理的返回值
2.后续处理执行有错,新任务的状态为失败,数据为异常对象
3.后续执行后返回的是一个任务对象,新任务的状态和数据于该任务对象一致
我的理解:执行失败态或完成态取决于前一个Promise的执行情况,或调用情况
原顺序>
练习1
const pro1 = new Promise((resolve,reject)=>{ //优先级1
setTimeout(()=>{ //优先级3 //执行成功,下次完成态
resolve(1);//给完成态1传入1
},1000);
})
const pro2 = pro1.then((data)=>{ //优先级4
console.log(data);//此时data为1,输出1 //执行成功,下次完成态
return data + 1;//给完成态2传入2
})
const pro3 = pro2.then((data)=>{//优先级5 //执行
console.log(data);//此时data为2,输出2
})
console.log(pro1,pro2,pro3);//优先级2,此时Promise123还都是运行中,无结果,输出pending
setTimeout(()=>{//优先级6
console.log(pro1,pro2,pro3);//全部执行完成,pro1为1,pro2为2,pro3没有返回值
},2000)
//答案
//Promise{<pending>} Promise{<pending>} Promise{<pending>}
//1
//2
//Promise{<fulfilled>:1} Promise{<fulfilled>:2} Promise{<fulfilled>:undefined}
练习2
new Promise((resolve , reject)=>{ //优先级1
resolve(1); //完成态传入1 //调用成功态
})
.then((res)=>{ //优先级2
console.log(res);//输出1 //执行成功,下次完成态
return 2;//完成态传入2
})
.catch((err)=>{ //由于没有失败,不执行失败态 //跳过
return 3;
})
.then((res)=>{ //优先级3 //执行
console.log(res); //输出2
})
//答案
//1
//2
练习3
new Promise((resolve , reject)=>{ //优先级1
resolve(); //调用成功态
})
.then((res)=>{//执行
console.log(res.toString());//报错,下一段执行失败态//执行失败,下次失败态
return 2; //上段报错了,这里不执行
})
.catch((err)=>{ //执行
return 3; //这段成功执行了,下一段执行完成态 //执行成功,下次成功态
})
.then((res)=>{ //执行 //执行
console.log(res); //输出3
})
//答案
//3
练习4
new Promise((resolve , reject)=>{
throw new Error(1); //抛出错误1,执行失败态 //执行失败,下次失败态
})
.then((res)=>{ //不执行
return new Error("2"); //跳过
})
.catch((err)=>{ //执行 //执行失败,下次失败态
throw err;
})
.then((res)=>{ //不执行 //跳过
console.log(res);
})
//答案
//抛出错误1
练习5
const pro1 = new Promise((res,rej)=>{
setTimeout(() => { //调用失败态
rej();
},1000);
})
const pro2 = pro1.catch(()=>{
return 2; //返回2
})
console.log(pro1);
console.log(pro2);
setTimeout(()=>{
console.log(pro1);
console.log(pro2);
},2000)
//答案
//Promise {<pending>}
//Promise {<pending>}
//Promise {<rejected>: undefined}
//Promise {<fulfilled>: 2}
练习6
const pro1 = new Promise((res, rej) => {
console.log(1) //1
rej();
})
const pro2 = pro1.catch(() => {
return 2;
})
console.log(pro1); //2
console.log(pro2); //3
setTimeout(() => {
console.log(pro1); //4
console.log(pro2); //5
}, 2000)
//答案
//1
//Promise {<rejected>: undefined}
//Promise {<pending>}
//Promise {<rejected>: undefined}
//Promise {<fulfilled>: 2}
练习7
const pro1 = new Promise((res, rej) => {
console.log(1) //1
setTimeout(() => {
rej();
},1000);
})
const pro2 = pro1.catch(() => {
return 2;
})
console.log(pro1); //2,没执行完所以是pending
console.log(pro2); //3
setTimeout(() => {
console.log(pro1); //4
console.log(pro2); //5
}, 2000)
//答案
//1
//Promise {<pending>}
//Promise {<pending>}
//Promise {<rejected>: undefined}
//Promise {<fulfilled>: 2}
练习8
const pro1 = new Promise((res, rej) => {
console.log(1) //1
setTimeout(() => {
console.log(5) //4
rej();
}, 2000);
})
const pro2 = pro1.catch(() => {
return 2;
})
console.log(pro1); //2
console.log(pro2); //3
setTimeout(() => {
console.log(pro1); //5
console.log(pro2); //6
console.log(3) //7
}, 2000)
//答案
//1
//Promise {<pending>}
//Promise {<pending>}
//5
//Promise {<rejected>: undefined}
//Promise {<fulfilled>: 2}
//3
练习9
const promise =new Promise((resolve,reject)=>{
console.log(1);
resolve();
console.log(2);
});
promise.then(()=>
console.log(3));
console.log(4);
//答案
//1
//2
//4
//3
练习10(我也不会)
Promise.resolve().then(() => {
console.log(0);
return Promise.resolve(4)
}).then(res => {
console.log(res);
}).then(()=>{
console.log(7);
})
Promise.resolve().then(() => {
console.log(1);
}).then(() => {
console.log(2);
}).then(() => {
console.log(3);
}).then(() => {
console.log(5);
}).then(() =>{
console.log(6);
})
Promise的静态方法
Promise.resolve(data) --> 直接返回一个完成状态的任务
Promise.reject(reason) --> 直接返回一个拒绝状态的任务
Promise.all(任务数组) --> 返回一个任务,任务数组全部成功则成功,任何一个失败则失败
Promise.any(任务数组) --> 返回一个任务,任务数组任一成功则成功,任务全部失败则失败
Promise.allSettled(任务数组) --> 返回一个任务,任务数组全部已决则成功,该任务不会失败
Promise.race(任务数组) --> 返回一个任务,任务数组任一已决则已决,状态和其一致
async
async关键字用于修饰函数,被它修饰的函数,一定返回Promise
await
await关键字表示等待某个Promise完成,它必须用于async函数中
await也可以等待其他资源
如果需要针对失败的任务进行处理,可以使用try-catch语法
例:
async function method(){
try{
const n = await Promise.reject(123); //执行失败态
console.log("成功",n); //不执行
}
catch(err){
console.log("失败",err) //执行这里
}
}
method();
async/await用例
function delay(duration){...}
//原 //改写
delay(1000) --> //(async () => {
.then(()=>{ // for (let i = 0;i<3;i++){
console.log("ok"); // await delay(1000);
return delay(1000); // console.log("ok");
}) // }
.then(()=>{ //})();
console.log("ok");
return delay(1000);
})
.then(()=>{
console.log("ok");
return delay(1000);
})