1、什么是Promise
Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法。(ps:关于原型:JavaScript高级 构造函数与原型篇)
Promise对象有以下两个特点。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
Promise功能:避免了回调地狱,把异步代码改成调用起来像同步代码。
// 语法:// Promise————// var p = new Promis(回调函数)// 回调函数也有两个参数// resolve ---------坚定// reject-----------拒绝var p = new Promise((resolve,reject)=>{//默认状态——————pending// 调用函数----resolve();// 得到// 成功状态————fulfilled// 调用函数——--reject()// 失败状态————rejected // resolve();reject();})console.log(p);// 特点:1、转态不受外部影响// 2、状态一旦发生改变,将不再变化
Promise的基本用法:
// 默认pending: 初始状态
var p=new Promise(function (resolve,reject) {if("操作成功"){resolve();//pending-->fulfilled 异步操作成功的回调函数}else{reject(); //pending-->reject 异步操作失败的回调函数}
})
p.then(data => {//在外面调用then处理成功的逻辑console.log("处理成功的逻辑");//fulfilled
}).catch(err=>{//在外面调用catch处理失败的逻辑console.log("失败的逻辑");//reject
})
// then方法会在异步成功后调用,catch方法会在异步失败后调用如果需要连续调用,就要用return比如:p1.then(data1 => {console.log(data1);return p2}).then(data2 => {console.log(data2);return p3}).then(data3 => {console.log(data3);})
2、Promise方法的使用
2.1、all方法
接收一个Promise实例对象组成的数组,[p1,p2,p3]
只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
const p1 = new Promise((resolve, reject) => {setTimeout(() => {reject("失败");}, 3000);
});
const p2 = new Promise((resolve, reject) => {setTimeout(() => {resolve("成功2");}, 2000);
});
const p3 = new Promise((resolve, reject) => {setTimeout(() => {resolve("成功3");}, 1000);
});// 全部成功返回成功,有一个失败返回失败
let p = Promise.all([p1, p2, p3]).then((res) => console.log(res)).catch(err=>console.log(err));
2.2、allSettled方法
接收一个Promise实例对象组成的数组,[p1,p2,p3]
返回是一个promise,then回调函数中得到每一个promise的详细结果,无论该promise是成功还是失败
const p1 = new Promise((resolve, reject) => {setTimeout(() => {reject('ok1')}, 3000)})const p2 = new Promise((resolve, reject) => {setTimeout(() => {//resolve('ok2')//reject('出错啦')}, 1000)})const p3 = new Promise((resolve, reject) => {setTimeout(() => {reject('ok3')}, 1000)})Promise.allSettled([p1, p2, p3]).then((res) => {console.log(res)}).catch((err) => {console.log(err)})
2.3、any方法
接收一个Promise实例对象组成的数组,[p1,p2,p3]
只要有一个成功的promise对象,就返回这个成功的Promise
const p1 = new Promise((resolve, reject) => {setTimeout(() => {reject('ok1')}, 3000)})const p2 = new Promise((resolve, reject) => {setTimeout(() => {//resolve('ok2')//reject('出错啦')}, 1000)})const p3 = new Promise((resolve, reject) => {setTimeout(() => {reject('ok3')}, 1000)})Promise.any([p1, p2, p3]).then((res) => {console.log(res) }).catch((err) => {console.log(err)})
2.4、race方法
all是等所有的异步操作都执行完了再执行then方法,那么race方法就是相反的,谁先执行完成就先执行回调。先执行完的不管是进行了race的成功回调还是失败回调,其余的将不会再进入race的任何回调
function promiseClick1(){let p = new Promise(function(resolve, reject){setTimeout(function(){var num = Math.ceil(Math.random()*20); //生成1-10的随机数console.log('2s随机数生成的值:',num)if(num<=10){resolve(num);}else{reject('2s数字太于10了即将执行失败回调');}}, 2000);})return p}function promiseClick2(){let p = new Promise(function(resolve, reject){setTimeout(function(){var num = Math.ceil(Math.random()*20); //生成1-10的随机数console.log('3s随机数生成的值:',num)if(num<=10){resolve(num);}else{reject('3s数字太于10了即将执行失败回调');}}, 3000);})return p}function promiseClick3(){let p = new Promise(function(resolve, reject){setTimeout(function(){var num = Math.ceil(Math.random()*20); //生成1-10的随机数console.log('4s随机数生成的值:',num)if(num<=10){resolve(num);}else{reject('4s数字太于10了即将执行失败回调');}}, 4000);})return p}Promise.race([promiseClick3(), promiseClick2(), promiseClick1()]).then(function(results){console.log('成功',results);},function(reason){console.log('失败',reason);});
2.5、catch方法
与Promise对象方法then方法并行的一个方法就是catch,与try catch类似,catch就是用来捕获异常的,也就是和then方法中接受的第二参数rejected的回调是一样的,如下:
function promiseClick(){let p = new Promise(function(resolve, reject){setTimeout(function(){var num = Math.ceil(Math.random()*20); //生成1-10的随机数console.log('随机数生成的值:',num)if(num<=10){resolve(num);}else{reject('数字太于10了即将执行失败回调');}}, 2000);})return p}promiseClick().then(function(data){console.log('resolved成功回调');console.log('成功回调接受的值:',data);}).catch(function(reason, data){console.log('catch到rejected失败回调');console.log('catch失败执行回调抛出失败原因:',reason);});
2.7、resolve方法与reject方法
resolve返回一个成功的promise
reject返回一个失败的promise
function promiseClick(){let p = new Promise(function(resolve, reject){setTimeout(function(){var num = Math.ceil(Math.random()*20); //生成1-10的随机数console.log('随机数生成的值:',num)if(num<=10){resolve(num);}else{reject('数字太于10了即将执行失败回调');}}, 2000);})return p}promiseClick().then(function(data){console.log('resolved成功回调');console.log('成功回调接受的值:',data);}, function(reason){console.log('rejected失败回调');console.log('失败执行回调抛出失败原因:',reason);});