一、为什么要引入Promise
在介绍本章之前,首先先抛出几个问题:
- Promise解决了什么问题?
- Promise有哪些具体的使用场景?
Promise解决了什么问题?
- 回调地狱问题
在没有Promise之前,前端获取数据往往需要通过回调函数层层嵌套的方式来解决异步问题,例如下面这段代码实例:
// 回调地狱实例
// 奶茶函数
function getTea(fn) {
setTimeout(() => {
fn('获取到一杯奶茶')
},2000)
}
// 面包函数
function getBread(fn) {
setTimeout(() => {
fn('获取到一个面包')
},100)
}
// 如果必须按照顺序获取,而不是根据时间,要求是先获取到奶茶后获取到面包。
getTea(function(data) {
console.log(data);
getBread(function(data) {
console.log(data);
})
})
- 可读性问题
通过Promise我们可以将上面的代码重写为下面的方式,明显这样可读性更高。
// 下面解释下,如何通过Promise来解决回调地狱的问题
function getTea() {
return new Promise((resolve) => {
setTimeout(() => {
resolve('获取到一杯奶茶')
}, 2000)
})
}
function getBread() {
return new Promise((resolve) => {
setTimeout(() => {
resolve('获取到一个面包')
}, 500)
})
}
getTea()
.then(res => {
console.log(res);
return getBread();
})
.then(res => {
console.log(res);
})
- 信任问题(也叫回调多次执行问题)
传统的回调函数无法保证只被执行一次,回调函数还要可能被执行其他操作,而Promise调用且仅调用一次resolve,不会产生回调多次执行的问题,所以Promise很好的解决了第三方库多次调用回调的问题。
Promise有哪些具体的使用场景?
- 场景1:将图片的加载写成一个Promise,图片一旦加载完成,Promise的状态就会发生变化。
- 场景2:当下一个异步请求需要依赖上一个请求结果的时候,可以通过链式操作解决问题。
- 场景3:通过all()实现多个请求合并在一起,汇总所有的请求结果,只需设置一个loading即可。
- 场景4:通过race()可以设置图片请求超时。