1、什么是Promise
Promise 是异步编程的一种解决方案,解决回调地狱问题,其实是一个构造函数(从语法上来说是对象--一切皆对象),Promise构造函数上有all、race、reject、resolve这几个方法,原型上有then、catch、finally等方法
console.log(Promise.all,Promise.race,Promise.resolve,Promise.reject) //控制台打印 ƒ all() { [native code] } ƒ race() { [native code] } ƒ resolve() { [native code] } ƒ reject() { [native code] } console.log(Promise.prototype) //控制台打印 Promise {Symbol(Symbol.toStringTag): "Promise", constructor: ƒ, then: ƒ, catch: ƒ, finally: ƒ}
Promise特点
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的
2、Promise 语法
let promise = new Promise((reslove,reject) => { if(true) { /** 成功 */ resolove('成功') }else { /** 失败 */ reject('失败'); } })
a、构造函数中的方法解析
1)Promise.all
all方法,该方法提供了并行执行异步操作的能力(同时获取多个异步执行结果),并且在所有异步操作执行完后并且执行结果都是成功的时候才执行成功回调;否则当所有异步操作执行中只要有一个结果为失败,则执行失败回调,捕获第一个失败的结果,并返回该结果。
all方法接受数组作为入参,数组项即为所有需要异步执行的方法。
全部成功
//所有异步执行结果为成功时 let promise1 = new Promise((resolve,reject) => { console.log('promise1'); resolve('promise1成功'); }); let promise2 = new Promise((resolve,reject) => { console.log('promise1'); resolve('promise2成功'); }) let promise3 = new Promise((resolve,reject) => { console.log('promise3'); resolve('promise3成功'); }) let promise = Promise.all([promise1,promise2,promise3]) promise.then((res) => { console.log(res); }).catch((rej)=> { console.log(rej) }) //控制台打印结果 promise1 promise2 promise3 ["promise1成功", "promise2成功", "promise3成功"]
执行结果有失败
//所有异步执行结果中有失败时,捕获第一个失败结果 let promise1 = new Promise((resolve,reject) => { console.log('promise1'); resolve('promise1成功'); }); let promise2 = new Promise((resolve,reject) => { console.log('promise1'); reject('promise2失败'); }) let promise3 = new Promise((resolve,reject) => { console.log('promise3'); reject('promise3失败'); }) let promise = Promise.all([promise1,promise2,promise3]) promise.then((res) => { console.log(res); }).catch((rej)=> { console.log(rej) }) //控制台打印结果 promise1 promise1 promise3 promise2失败
2)Promise.race
Promise.all是等所有的异步操作都执行完了再执行then方法,那么race方法就是相反的,谁先执行完成就先执行回调。先执行完的不管是进行了race的成功回调还是失败回调,其余的将不会再进入race的任何回调
let promise1 = new Promise((resolve,reject) => { setTimeout(()=> { resolve('promise1成功回调') },3000) }) let promise2 = new Promise((resolve,reject) => { setTimeout(()=>{ reject('promise2失败回调') },1000) }) let promise3 = new Promise((resolve,reject) => { setTimeout(()=> { resolve('promise3成功回调') },5000) }) let promise = Promise.race([promise1,promise2,promise3]) promise.then((res) => { console.log(res); }).catch((rej)=> { console.log(rej) }) //控制台打印 promise2失败回调
3) Promise.resolve
Promise.resolve方法的作用将现有对象转为Promise对象,把对象转为Promise对象。而该对象作为入惨传入.then中
let foo = { name: 'haha' } Promise.resolve(foo).then((res)=> { console.log(res) })
打印结果
4)Promise.reject
Promise.reject(对象)方法返回一个Promise实例,与resolve方法用法相同,此时的promise状态为rejected,该对象作为参数传入.catch中
b、原型上的方法解析
1).then方法
用法一:.then((res)=>{})--成功回调 .catch((rej) => {}) --- 失败回调
let promise = new Promise((resolve,reject) => { if(false) { // resolve(value)是在Promise在已经异步完成成功(Resolved)之后执行的 resolve('成功回调'); }else { // reject(value)是在Promise在异步失败之后(Rejected)执行。 reject('失败回调'); } }) promise.then((res) => { console.log(res); }).catch((rej) => { console.log(rej) })
用法二: .then((res) => {},(rej)=>{})
let promise = new Promise((resolve,reject) => { if(false) { // resolve(value)是在Promise在已经异步完成成功(Resolved)之后执行的 resolve('成功回调'); }else { // reject(value)是在Promise在异步失败之后(Rejected)执行。 reject('失败回调'); } }) promise.then((res) => { // 成功回调 console.log(res); },(rej) => { // 失败回调 console.log(rej) })
⚠️ 注意:不论是.then还是.catch返回的都是Promise实例,而每个Promise实例都是从pending(进行中)到resolved(已完成) 或 从pending(进行中)到rejected(已失败)状态的过程
let promise = new Promise((resolve,reject) => { if(false) { // resolve(value)是在Promise在已经异步完成成功(Resolved)之后执行的 resolve('成功回调'); }else { // reject(value)是在Promise在异步失败之后(Rejected)执行。 reject('失败回调'); } }) promise.then((res) => { consle.log('一个then') }).then((res)=> { console.log('另一个then') }).catch((rej)=> { // Promise实例触发失败回调,第一个.catch 捕获到错误信息,当前.catch有状态pending到rejected(由于j未定义所以走失败回调) console.log('一个catch'); j }).catch((rej)=> { // 此.catch捕获到上一个错误信息,当前.catch有状态从pending到resolved console.log('另一个catch',rej) }).then((res) => { //最后捕获到成功消息 console.log('最后一个then') })
打印结果