一、是什么:
promise是异步编程的一种解决方案,它是一个对象,可以获取异步操作的信息,它的出现改善了异步编程,避免了地狱回调,它比传统的解决方案回调函数和事件更合理和更强大
二、promise的三种状态:
pending进行中,fulfilled已成功,rejected已失败
特点
- 对象的状态不受外界影响,只有异步操作的结果,可以决定当前是哪一种状态
- 一旦状态改变(从
pending
变为fulfilled
和从pending
变为rejected
),就不会再变,任何时候都可以得到这个结果
三、用法:
Promise
对象是一个构造函数,用来生成Promise
实例
const promise = new Promise(function(resolve, reject) {});
Promise
构造函数接受一个函数作为参数,该函数的两个参数分别是resolve
和reject
resolve
函数的作用是,将Promise
对象的状态从“未完成”变为“成功”reject
函数的作用是,将Promise
对象的状态从“未完成”变为“失败”
四、实例方法
Promise构建出来的实例方法:
then():then()是成功时的回调,
语法: p1.then(成功的回调函数[,失败的回调函数])
通过then传递的时候,调用失败的函数,没有报错提示
catch():catch()是失败时的回调,
语法: p1.catch(失败的回调函数)
通过catch传递的时候,调用失败的函数,有报错提示
finally():finally无论结果如何都会执行
let p1 = new Promise(function(resolve,reject){
setTimeout(function(){
let num = Math.random()
if(num>0.5){
// 成功
resolve(num)
}else{
// 失败
reject('数字小于等于0.5')
}
},3000)
})
// 1 promise对象的then方法
// 通过promise对象的then方法可以同时给p1传递成功和失败的回调函数
// 语法: p1.then(成功的回调函数[,失败的回调函数])
// 通过then传递的时候,调用失败的函数,没有报错提示
// p1.then((data)=>{
// // 成功的回调函数
// console.log('成功了')
// console.log(data)
// },(err)=>{
// // 失败的回调函数
// console.log("失败以后传递过来的信息是:"+err)
// })
// 2 promise对象的catch方法
// 通过promise对象的catch方法可以给p1传递失败的回调函数
// 语法: p1.catch(失败的回调函数)
// 通过catch传递的时候,调用失败的函数,有报错提示
p1.then((data)=>{
// 成功的回调函数
console.log('成功了')
console.log(data)
})
p1.catch((err)=>{
// 失败的回调函数
console.log("失败以后传递过来的信息是:"+err)
})
// 3 promise对象的finally方法
// 通过promise对象的finally方法可以给p1传递一个函数
// 这个函数会在在promise结束的时候执行,不管是成功还是失败
p1.finally(options=>{
console.log('不管成功还是失败,只要结束了,我就会执行')
console.log(options)
})
五、构造函数方法
Promise
构造函数存在以下方法:
- all()
- race()
- allSettled()
- resolve()
- reject()
- try()
all()
Promise.all()
方法用于将多个 Promise
实例,包装成一个新的 Promise
实例
const p = Promise.all([p1, p2, p3]);
接受一个数组(迭代对象)作为参数,数组成员都应为Promise
实例
实例p
的状态由p1
、p2
、p3
决定,分为两种:
- 只有
p1
、p2
、p3
的状态都变成fulfilled
,p
的状态才会变成fulfilled
,此时p1
、p2
、p3
的返回值组成一个数组,传递给p
的回调函数 - 只要
p1
、p2
、p3
之中有一个被rejected
,p
的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给p
的回调函数
注意,如果作为参数的 Promise
实例,自己定义了catch
方法,那么它一旦被rejected
,并不会触发Promise.all()
的catch
方法
const p1 = new Promise((resolve, reject) => { resolve('hello'); }) .then(result => result) .catch(e => e); const p2 = new Promise((resolve, reject) => { throw new Error('报错了'); }) .then(result => result) .catch(e => e); Promise.all([p1, p2]) .then(result => console.log(result)) .catch(e => console.log(e)); // ["hello", Error: 报错了]
如果p2
没有自己的catch
方法,就会调用Promise.all()
的catch
方法
const p1 = new Promise((resolve, reject) => { resolve('hello'); }) .then(result => result); const p2 = new Promise((resolve, reject) => { throw new Error('报错了'); }) .then(result => result); Promise.all([p1, p2]) .then(result => console.log(result)) .catch(e => console.log(e)); // Error: 报错了
race()
Promise.race()
方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例
const p = Promise.race([p1, p2, p3]);
只要p1
、p2
、p3
之中有一个实例率先改变状态,p
的状态就跟着改变
率先改变的 Promise 实例的返回值则传递给p
的回调函数
const p = Promise.race([ fetch('/resource-that-may-take-a-while'), new Promise(function (resolve, reject) { setTimeout(() => reject(new Error('request timeout')), 5000) }) ]); p .then(console.log) .catch(console.error);