可以这么理解Promise:
调用一个函数,这个函数中发送网络请求(我们可以用定时器来模拟)
如果发送网络请求成功了,那么告知调用者发送成功,并且将相关数据返回过去。
如果发送网络请求失败了,那么告知调用者发送失败,并且告知错误信息。
Promise的API:
在用new创建Promise对象时,我们需要传入一个回调函数,我们称之为executor。
这个回调函数会被立即执行,并且给传入另外两个回调函数,resolve、reject。
调用resolve回调函数时,会执行Promise对象的then方法传入的回调函数,
调用reject回调函数时,会执行Promise对象的catch方法传入的回调函数。
// 状态一旦确定下来,那么就是不可更改的(锁定)
new Promise((resolve,reject) => {
// pending状态:待定的
resolve() // 处于fulfilled状态(已敲定/兑现状态)
// reject() // 处于rejected状态(已拒绝状态)
}).then(res => {
console.log(res, 'res')
},err => {
console.log('err', err)
})
resolve(参数):
1、可传入普通的值或者对象: pending -> fulfilled
2、传入一个Promise: 那么当前的Promise的状态会由传入的Promise来决定,相当于状态进行了移交。
3、传入一个对象,并且这个对象有实现then方法,那么也会执行该then方法,且由这个then方法决定后续状态。
// 传入一个Promise的情况
const newPromise = new Promsie((resolve,reject) => {
reject('err message')
// resolve('aaaa')
})
new Promise((resolve,reject) => {
// pending -> fulfilled
resolve(newPromise)
}).then(res => {
console.log(res, 'res')
},err => {
console.log('err', err)
})
// 输出 err: err message
// 传入一个有then方法的对象
new Promise((resolve,reject) => {
// pending -> fulfilled
const obi = {
then: fuction(resolve,reject) {
// resolve('resolve message')
reject('reject message')
}
}
resolve(obj)
}).then(res => {
console.log(res, 'res')
},err => {
console.log('err', err)
})
// 输出: reject message
Promise有哪些对象方法:
console.log(Object.getOwnPropretyDescriptors(Promise.prototype))
Promise 对象方法
1、同一个Promise可以被多次调用then方法。当resolve方法被回调时,所有的then方法传入的回调函数都会被调用。
2、then方法传入的回调函数,可以有返回值。
3、如果返回的是一个Promise
4、如果返回的是一个对象,并且该对象实现了thenable(接口)
5、通过catch方法来传入错误捕获的回调函数
6、catch()的返回值。
7、finally: es9新增的一个特性,表示无论Promise对象变成fulfilled还是rejectd状态,最终都会被执行的代码。finally方法不接受参数。
// 1、同一个Promise可以被多次调用then方法.当resolve方法被回调时,所有的then方法传入的回调函数都会被调用。
const promise = new Promise((resolve,reject) => {
resolve('hahaha')
})
promise.then(res => {
console.log('res1:', res)
})
promise.then(res => {
console.log('res12:, res)
})
promise.then(res => {
console.log('res3:', res)
})
// 输出
res1: hahaha
res2: hahaha
res3: hahaha
// 2、then方法传入的回调函数,可以有返回值。
// then方法本身也是有返回值,它的返回值是Promise
// 如果返回的是一个普通值,那么这个普通的值被作为一个新的Promise的resolve值
const promise = new Promise((resolve,reject) => {
resolve()
})
promise.then(res => {
// 如果没有返回值,默认返回undefined
return('hahaha')
}).then(res => {
console.log("res: ",res)
})
// 输出 res: hahaha
// 3、如果返回的是一个Promise
promise.then(res => {
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve(111)
}, 3000)
})
}).then(res => {
console.log('res:', res)
})
// 三秒后输出: res: 111
// 4、如果返回的是一个对象,并且该对象实现了thenable(接口)
promise.then(res => {
// return 出去的是一个新的promise
return {
then: function(resolve,reject) {
resolve(222)
}
}
}).then(res => {
console.log('res:', res)
})
// 输出 res: 222
// 5、通过catch方法来传入错误捕获的回调函数
//
const promise = new Promise((resolve,reject) => {
resolve() // 第二种情况 resolve()
// reject('reject status') // 第一种情况 返回reject()
})
promise.then(res => {
return 1111
}).catch(err => {
console.log('err:', err)
})
// 如果是第一种情况 输出: err: reject status
// 第二种情况 无输出
// 6、catch方法的返回值,返回一个Promise对象
const promise = new Promise((resolve,reject) => {
reject('1111')
})
promise.then(res => {
console.log(res, 'res')
}).catch(err => {
console.log('err:', err)
return 'catch return value'
}).then(res => {
console.log('res result', res)
}).catch(err => {
console.log('err result', err)
})
// 输出: err: 1111
// finally
const promise = new Promise((resolve,reject) => {
reject('reject message')
})
promise.then(res => {
console.log('res',res)
}).catch(err => {
console.log('err:', err)
}).finally(() => {
console.log('finally code execute')
})
// 输出: err: reject message
// finally code execute
Promise类方法
1、resolve()
2、all():所有的Promise都变成fulfilled时,再拿到结果。在拿到所有结果之前,如果有一个Promise变成了rejected,那么整个promise都是rejected
3、allSettled():等所有promise都执行完有结果以后,把所有的值与状态返回,返回的格式是对象,不会进入catch。
4、race():只要有一个Promise变成fulfilled状态,那么就结束。如果拿到最先的状态是rejected,那么整个Promise.race都是rejected
5、any():是ES12中新增的方法,和race方法类似
// 类方法 Promise.resolve
const promise = Promise.resolve({name: 'why'})
// 相当于
//const promise2 = new Promise((resolve,reject) => {
// resolve({name: 'why'})
// })
promise.then(res => {
console.log('res:', res)
})
//输出 res: {name: 'why'}
// 2、Promise.all(): 所有的Promise都变成fulfilled时,再拿到结果
// 在拿到所有结果之前,如果有一个promise变成了rejected,那么整个promise都是rejected
const p1 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(1111)
}, 1000)
})
const p2 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(2222)
}, 1000)
})
const p3 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(333)
}, 1000)
})
//
Promise.all([p1,p2,p3]).then(res => {
console.log(res)
}).catch(err => {
console.log('err:打印出来的是变成rejected的值', err)
})
// 输出: [1111,2222,333]
// 3、Promise.allSettled(): 等所有promise都执行完有结果以后,把所有的值与状态返回,返回的格式是对象,不会进入catch。
const p1 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(1111)
}, 1000)
})
const p2 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(2222)
}, 1000)
})
const p3 = new Promise((resolve,reject) => {
setTimeout(() => {
rejected(333)
}, 1000)
})
//
Promise.all([p1,p2,p3]).then(res => {
console.log(res)
}).catch(err => {
console.log('err:', err)
})
// 输出: [{
status: 'fufilled', value, 1111
}, {
status: 'fufilled', value, 2222
}, {
status: 'rejected', value, 333
}
]
// race: 竞赛
// 只要有一个Promise变成fulfilled状态,那么就结束
// 意外:如果拿到最先的状态是rejected,那么整个Promise.race都是rejected
const p1 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(1111)
}, 1000)
})
const p2 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(2222)
}, 1000)
})
const p3 = new Promise((resolve,reject) => {
setTimeout(() => {
rejected(333)
}, 1000)
})
Promise.race([p1,p2,p3]).then(res => {
console.log('res:', res)
}).catch(err => {
console.log('err:', err)
})
// 输出 res: 1111
// any是ES12中新增的方法,和race方法类似
// 1、any方法会等到一个fulfilled状态,才会决定新Promise的状态,在then里返回fulfilled的值
// 2、如果所有的Promise都是reject,那么也会等到所有的Promise都变成rejected状态,然后执行catch()
const p1 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(1111)
}, 1000)
})
const p2 = new Promise((resolve,reject) => {
setTimeout(() => {
resolve(2222)
}, 1000)
})
const p3 = new Promise((resolve,reject) => {
setTimeout(() => {
rejected(333)
}, 1000)
})
Promise.any([p1,p2,p3]).then(res => {
console.log('res:', res)
}).catch(err => {
console.log('err:', err)
// 可以通过console.log(err.errors)拿到所有的错误信息
})