一、Promise引入
1、什么是回调函数?自定义一个回调函数代码演示一下
function f1(fn) {
let a =1;
console.log(a,'a')
fn()
}
f1(function() {
console.log('callback') // 1,'a' callback
})
注:可以看出回调函数和普通函数的区别是回调函数作为实参在一个函数中传递并调用。
2、什么是回调地狱?
回调地狱是指:多层嵌套函数,函数的返回值是下一个函数的执行条件。(因此回调地狱可以解决异步函数的执行顺序问题,但是随着带来的问题是可读性差)
二、Promise使用
3、什么是Promise?
Promise是异步编程的一种解决方案,它是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
4、promise是可以解决什么问题?
回调地狱问题。
5、能用简单的代码举例一下三层回调演示回调地狱吗?
setTimeout(function () { //第一层
console.log('张三');//等3秒打印张三在执行下一个回调函数
setTimeout(function () { //第二层
console.log('李四');//等2秒打印李四在执行下一个回调函数
setTimeout(function () { //第三层
console.log('王五');//等一秒打印王五
}, 1000)
}, 2000)
}, 3000)
6、上述代码用promise解决一下
Promise.resolve("张三")
.then((res)=>{
console.log(res);
return "李四"
}).then((res)=>{
console.log(res)
return "王五"
}).then((res)=>{
console.log(res)
})
注:这里只需要理解promise把回调地狱从横向增长改为纵向增加即可(即链式编程)。
7、简单介绍一下promise
首先promise是一种异步编程的解决方案,是为了解决回调地狱问题而引出的,它有三种状态:等待状态、成功、失败,一旦promise的状态只能改变一次,即后续调用同一个promise状态不会再4发生改变,Promise满足链式编程,即它每次调用后都可以返回一个Promise对象,Promise可以解决程序的执行顺序问题
8、Promise解决程序的执行顺序问题
背景:目前有单个Tab页,每个tab页的标签内容动态生成,而且每个tab页的数据也随tab页标签内容的不同而改变,其中tab标签内容和页面内容分开存储,目前的有两个接口:一个是获取所有标签的接口,一个是通过标签ID获取页面内容的接口,当前数据结构类型如下:
[{
id:'',
labelName:'',
},
...
]
[
{
labelId:'',
content:'',
}
...
]
①错误获取方式(默认typeList已经获取到了):
if(TypeList.value.length>0){
for(let item in TypeList.value){
axios.post('后台接口', '请求字段').then(res => {
if (res.success) {
typeItemList.value.push(res.obj.list);
}
}).catch(error=>{
console.error(error)
})
}
}
上面代码的问题在于axios默认是异步请求(程序50%的bug都是由异步引起的,格外注意),而通过数组循环方式请求后台可能会导致不会程序的执行顺序混乱。
②promise解决方案
if(TypeList.value.length>0){
let TemplateList=[];
for(let item in TypeList.value){
TemplateList.push(new Promise((resolve, reject) => {
api.post('后台请求接口', '请求参数').then(res => {
if (res.success) {
return resolve(res.obj);
}
}).catch(error=>{
console.error(error)
})
}));
}
Promise.all(TemplateList).then(res=>{
for(let item in res){
typeItemList.value.push(res[item].list);
}
})
}
注:promise.all()该方法用于将多个Promise实例,包装成一个新的Promise实例。(等到所有的请求结束后才会走then方法,从而保证了执行顺序问题)
参考文章: