ES 6 Promise的用法
一 、为什么要使用Promise
“ 回调地狱 ”这个词,不知道大家听过没有,就是异步调用获取到结果后,
为下一个异步函数提供 参数,所以就会一层一层的出现回调里面 嵌入回调,导致层次很深,代码维护起来特别的复杂,看一下下面的小案例大家就知道什么意思了。
以uni.request( ) 为例
下面的举例就 以uniapp里面的网络请求uni.request()为例了,
如果你做的是微信小程序wx.request()也是一样的,还有jQuery的ajax(),
这些都是异步请求 ,
通过success回调函数获取数据的,
那有童鞋会问为什么不适用vue的axios那,因为axios网络请求已经封装了promise了。
getData(){
//获取分类列表id
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/navlist.php",
success:res=>{
let id=res.data[0].id
// 根据分类id获取该分类下的所有文章
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/newslist.php",
data:{
cid:id
},
success:res2=>{
//获取到一篇文章的id,根据文章id找到该文章下的评论
let id=res2.data[0].id;
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/comment.php",
data:{
aid:id
},
success:res3=>{
//找到该文章下所有的评论
console.log(res3)
}
})
}
})
}
})
}
大家看到上的代码了没有,数一数有几层嵌套,出现了几个success回调,这个案例的嵌套还算是少的那,还有比这更夸张的,这就是所谓的回调地狱,层层嵌套,要是维护起这样的代码来,直接会把新手劝退的,自己写过的代码要是不加注释也不知道这到底是干嘛的。
在没有ES6的promise时候原来是怎么优化的那,把每一个request请求封装出一个函数将结果进行返回,这就是原来常用的回调函数方案,将上述代码可以改造成如下代码:
1 . 0 版本 ( 封装函数 )
调用部分 ↓
//在onload初始化后调用相应的函数
onLoad() {
//调用导航函数,并拿到函数的返回值
this.getNav(res=>{
let id=res.data[0].id;
//拿到分类id作为参数
this.getArticle(id,res2=>{
//拿到文章id作为参数
let id=res2.data[0].id;
this.getComment(id,res3=>{
//最终获取到第一个分类下,第一篇文章下,所有评论
console.log(res3)
})
})
});
}
**封装的函数部分↓ **
methods: {
//先获取导航分类接口,将结果进行返回,到调用函数的地方获取
getNav(callback){
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/navlist.php",
success:res=>{
callback(res)
}
})
},
//获取文章数据,将文章列表进行返回
getArticle(id,callback){
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/newslist.php",
data:{
cid:id
},
success:res=>{
callback(res)
}
})
},
//获取文章下的所有评论
getComment(id,callback){
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/comment.php",
data:{
aid:id
},
success:res=>{
callback(res)
}
})
}
}
小结: 我们通过封装 方法 从而简化代码 让代码看起来更加清晰 ( 至少在看调用函数方面 会更加清晰 ), 但是并没有很好解决回调地狱的问题
二 、什么是 Promise
promise是解决异步的方法,本质上是一个构造函数,
可以用它实例化一个对象。对象身上有resolve、reject、all,原型上有then、catch方法。
promise对象有三种状态:
pending(初 识状态/进行中)、resolved或fulfilled(成功)、rejected(失败)
下面我们直接打印一下 Promise
console.dir(Promise)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mVlwddYH-1675075189316)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20230130121411121.png)]
三 、将回调函数修改为 Promise 方案
2.0 版本 ( Promise 对象 )
.then 的链式调用函数
//promise链式调用
this.getNav().then(res=>{
let id=res.data[0].id;
return this.getArticle(id);
}).then(res=>{
let id=res.data[0].id;
return this.getComment(id)
}).then(res=>{
console.log(res)
})
函数封装也需要进行修改
methods: {
//先获取导航分类接口,将结果进行返回,到调用函数的地方获取
getNav(callback){
return new Promise((resolve,reject)=>{
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/navlist.php",
success:res=>{
resolve(res)
},
fail:err=>{
reject(err)
}
})
})
},
//获取文章数据,将文章列表进行返回
getArticle(id){
return new Promise((resolve,reject)=>{
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/newslist.php",
data:{
cid:id
},
success:res=>{
resolve(res)
},
fail:err=>{
reject(err)
}
})
})
},
//获取文章下的所有评论
getComment(id){
return new Promise((resolve,reject)=>{
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/comment.php",
data:{
aid:id
},
success:res=>{
resolve(res)
},
fail:err=>{
reject(err)
}
})
})
}
看完上面两段代码 , 下面我们进行详细的分析
很多初学者不是很清楚 .then 以及里面的一些参数等等
下面, 我们结合 上面的案例进行讲解
首先, 在上面, 我们通过 console.log(Promise) 可以知道里面
包括了 then() catch() 等方法
所以我们要原来的调用函数的返回值 改成
返回 Promise 对象
在此之前我们需要对 // 对象 进行实例化
如下面:
getNav(callback){
return new Promise((resolve,reject)=>{
........
})
},
// 也可以下面这种写法
getNav(callback){
// 实例化
let p = new Promise((resolve,reject)=>{
........
})
return p
},
有关于实例化 Promise 中的两个参数 (resolve,reject)
// 和 1.0 版本中 callblack 的作用差不多 主要起了回调数据的作用
// 不过, resolve 是表示运行成功的返回的数据 reject是表示运行失败返回的数据
getNav(callback){
return new Promise((resolve,reject)=>{
uni.request({
........,
success:res=>{
resolve(res)
},
fail:err=>{
reject(err)
}
})
})
},
四、await / async ES7的新规范,异步处理同步化
注意文章来源:https://www.toymoban.com/news/detail-593782.html
// await / async 两者需要一起使用, 才能起作用, 缺一不可
如果使用了await 没有在函数中使用async 命令, 就会报错
如果使用了async 没有使用await 不会报错 但没有意义
3 . 0 版本
async onLoad() {
let id,res;
res=await this.getNav();
id=res.data[0].id;
res=await this.getArticle(id);
id=res.data[0].id;
res=await this.getComment(id);
console.log(res)
}
关于封装函数部分和 then的链式调用的封装的代码一样
特别声明: 本文章并非本人完全原创, 只是对虾米老师的笔记进行简化以及添加一些自己的见解
还有就是 如果笔记有什么问题, 欢迎大家在评论区或者私信或者我们的交流群斧正。
我也是小白,希望和大家一起进步。
最后祝大家新年快乐!!!!
课程链接: https://www.bilibili.com/video/BV1XW4y1v7Md?share_source=copy_web文章来源地址https://www.toymoban.com/news/detail-593782.html
到了这里,关于异步同步化( Promise 详解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!