Promise三个状态
- pending: 初始状态,既没有被兑现,也没有被拒绝(当执行executor中的代码时,处于该状态)
- fulfilled:操作成功完成(执行了resolve时,处于该状态)
- rejected:操作失败(执行了reject时,处于该状态)
function requestData(url) {
return new Promise((resolve, reject) => {
if (url === '123') {
resolve('成功')
} else {
reject('失败')
}
})
}
requestData('123').then(res => {
console.log(res); // 成功
}).catch(err => {
console.log(err);
})
requestData('321').then(res => {
console.log(res);
}).catch(err => {
console.log(err); // 失败
})
Promise的Executor
Executor是在创建Promise时需要传入的一个回调函数,这个回调函数会被立即执行,并且传入两个参数
new Promise((resolve, reject) => {
console.log('Executor');
})
// then中接收两个参数,第二个是失败的回调
// new Promise((resolve, reject) => {
// console.log('Executor');
// }).then(res => {
// console.log('res', res);
// }, err => {
// console.log('err', err);
// })
通常我们会在Executor中确定我们的Promise状态
- 通过resolve,可以兑现(fulfilled)Promise的状态,我们也可以称之为已决议(resolved)
- 通过reject,可以拒绝(reject)Promise的状态
- 一旦状态被确定下来,Promise的状态会被 锁死,该Promise的状态是不可更改的
Promise的resolve参数
- 传入的是普通的值或者对象,那么这个值会作为then回调的参数
new Promise((resolve, reject) => {
resolve('11')
}).then(res => {
console.log('res', res); // 11
}, err => {
console.log('err', err);
})
- 传入的是另外一个Promise,那么这个新Promise会决定原Promise的状态
new Promise((resolve, reject) => {
resolve(new Promise((resolve1, reject1) => {
// 如果这里没有调resolve1, 或者reject1,那么整个状态都将是pending状态
// 换句话说就是:这个Promise会决定原Promise的状态
}))
}).then(res => {
console.log('res', res);
}, err => {
console.log('err', err);
})
- 传入的是一个对象,并且这个对象有实现then方法,那么会执行该then方法,并且根据then方法的结果来决定Promise的状态
new Promise((resolve, reject) => {
resolve({
then(resolve1, reject1) {
resolve1('222')
}
})
}).then(res => {
console.log('res', res); // 222
}, err => {
console.log('err', err);
})
Promise的then方法
then方法是Promise对象上的一个方法:它其实是放在Promise的原型上的 Promise.prototype.then
console.log(Object.getOwnPropertyDescriptors(Promise.prototype));
then方法接受两个参数:
- fulfilled的回调函数:当状态变成fulfilled时会回调的函数
- reject的回调函数:当状态变成reject时会回调的函数
then方法多次调用
const promise = new Promise((resolve, reject) => {
resolve('1')
})
// 这三个都会执行
promise.then(res1 => {
console.log('res1', res1);
})
promise.then(res2 => {
console.log('res2', res2);
})
promise.then(res3 => {
console.log('res3', res3);
})
then方法 传入的回调函数,可以有返回值
- 返回一个普通的值:这个普通的值被作为一个新的Promise的resolve的值
const promise = new Promise((resolve, reject) => {
resolve('1')
})
promise.then(res => {
return '2'
}).then(res => {
console.log(res); // 2
})
这段代码的两个then的使用,可以上面then多次调用的代码不一样哟
- 返回一个Promise
const promise = new Promise((resolve, reject) => {
resolve('1')
})
promise.then(res => {
return new Promise((resolve, reject) => {
resolve('2')
})
}).then(res => {
console.log(res); // 2
})
- 返回一个对象,并且这个对象有实现then方法
const promise = new Promise((resolve, reject) => {
resolve('1')
})
promise.then(res => {
return {
then(resolve, reject) {
resolve('2')
}
}
}).then(res => {
console.log(res); // 2
})
Promise的catch方法
const promise = new Promise((resolve, reject) => {
reject('1')
})
promise.catch(err => {
console.log(err);
})
catch方法 返回值
const promise = new Promise((resolve, reject) => {
reject('1')
})
// 在catch中return,他也相当于是执行resolve,所以他会到then,除非手动reject或者throw
promise.then(() => {
console.log('then');
}).catch(() => {
return '222'
}).then(res => {
console.log('res', res);
}).catch((err) => {
console.log('err', err);
})
Promise的finally方法
finally是在ES9中新增的一个特性:表示无论Promise对象无论变成fulfilled还是reject状态,最终都会被执行的代码。finally方法是不接收参数的,因为无论前面是fulfilled状态,还是reject状态,它都会执行。
const promise = new Promise((resolve, reject) => {
resolve('1')
})
promise.then(() => {
console.log('then');
}).catch(() => {
console.log('catch');
}).finally(() => {
console.log('finally');
})
Promise的resolve方法
在之前讲的then,catch,finally这三个是实例方法也叫对象方法,接下来我们来看他的类方法。
// 将一个对象转为promise
const promise = Promise.resolve({ name: 'xt' })
// 相当于
const promise1 = new Promise(resolve => {
resolve({ name: 'xt' })
})
resolve参数:
- 参数是一个普通的值或者对象
- 参数本身是Promise
- 参数是一个thenable
Promise的reject方法
const promise = Promise.reject({ name: 'xt' })
// 相当于
const promise1 = new Promise((resolve, reject) => {
reject({ name: 'xt' })
})
Promise.reject传入的参数无论是什么形态,都会直接作为reject状态的参数传递到catch的
Promise的all方法
- 它的作用是将多个Promise包裹在一起形成一个新的Promise
- 新的Promise状态由包裹的所有Promise共同决定
- 结果值是数值
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000);
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2)
}, 2000);
})
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(3)
}, 3000);
})
// 只要有一个promise为rejected,那么所有的promise为rejected
Promise.all([promise1, promise2, promise3]).then(res => {
console.log(res); // [ 1, 2, 3 ]
}).catch(err => {
console.log(err);
}))
Promise的allSettled方法
因为all方法我们上面说过只要有一个promise为rejected,那么所有的promise为rejected,那么对于resolved的,以及依然处于pending状态的Promise,我们是获取不到对应的结果的,所以在ES11中有了Promise.allSettled。
该方法会在所有的Promise都有结果(settled),无论是fulfilled,还是reject时,才会有最终的状态,并且这个Promise的结果一定是fulfilled的
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000);
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(2)
}, 2000);
})
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(3)
}, 3000);
})
Promise.allSettled([promise1, promise2, promise3]).then(res => {
console.log('res', res); // [{ status: 'fulfilled', value: 1 },{ status: 'rejected', reason: 2 },{ status: 'fulfilled', value: 3 }]
}).catch(err => {
console.log('res', err);
})
Promise的race方法
如果有一个Promise有了结果,我们就希望决定最终新Promise的状态,那么可以使用race方法
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000);
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(2)
}, 2000);
})
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(3)
}, 3000);
})
Promise.race([promise1, promise2, promise3]).then(res => {
console.log('res', res); // 1
}).catch(err => {
console.log('res', err);
})
Promise的any方法
- any方法是ES12中新增的方法,和race方法是类似的。
- any方法会等到一个fulfilled状态,才会决定新Promise的状态
- 如果所有的Promise都是reject的,那么也会等到所有的Promise都变成rejected状态
- 如果所有的Promise都是reject的,那么会报一个AggregateError的错误
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(1)
}, 1000);
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2)
}, 2000);
})
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(3)
}, 3000);
})
Promise.any([promise1, promise2, promise3]).then(res => {
console.log('res', res); // 2
}).catch(err => {
console.log('res', err);
})