ES 6 Promise的用法
一 、為什么要使用Promise
“ 回調(diào)地獄 ”這個詞,不知道大家聽過沒有,就是異步調(diào)用獲取到結(jié)果后,
為下一個異步函數(shù)提供 參數(shù),所以就會一層一層的出現(xiàn)回調(diào)里面 嵌入回調(diào),導(dǎo)致層次很深,代碼維護起來特別的復(fù)雜,看一下下面的小案例大家就知道什么意思了。
以uni.request( ) 為例
下面的舉例就 以uniapp里面的網(wǎng)絡(luò)請求uni.request()為例了,
如果你做的是微信小程序wx.request()也是一樣的,還有jQuery的ajax(),
這些都是異步請求 ,
通過success回調(diào)函數(shù)獲取數(shù)據(jù)的,
那有童鞋會問為什么不適用vue的axios那,因為axios網(wǎng)絡(luò)請求已經(jīng)封裝了promise了。
getData(){
//獲取分類列表id
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/navlist.php",
success:res=>{
let id=res.data[0].id
// 根據(jù)分類id獲取該分類下的所有文章
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/newslist.php",
data:{
cid:id
},
success:res2=>{
//獲取到一篇文章的id,根據(jù)文章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)
}
})
}
})
}
})
}
大家看到上的代碼了沒有,數(shù)一數(shù)有幾層嵌套,出現(xiàn)了幾個success回調(diào),這個案例的嵌套還算是少的那,還有比這更夸張的,這就是所謂的回調(diào)地獄,層層嵌套,要是維護起這樣的代碼來,直接會把新手勸退的,自己寫過的代碼要是不加注釋也不知道這到底是干嘛的。
在沒有ES6的promise時候原來是怎么優(yōu)化的那,把每一個request請求封裝出一個函數(shù)將結(jié)果進行返回,這就是原來常用的回調(diào)函數(shù)方案,將上述代碼可以改造成如下代碼:
1 . 0 版本 ( 封裝函數(shù) )
調(diào)用部分 ↓
//在onload初始化后調(diào)用相應(yīng)的函數(shù)
onLoad() {
//調(diào)用導(dǎo)航函數(shù),并拿到函數(shù)的返回值
this.getNav(res=>{
let id=res.data[0].id;
//拿到分類id作為參數(shù)
this.getArticle(id,res2=>{
//拿到文章id作為參數(shù)
let id=res2.data[0].id;
this.getComment(id,res3=>{
//最終獲取到第一個分類下,第一篇文章下,所有評論
console.log(res3)
})
})
});
}
**封裝的函數(shù)部分↓ **
methods: {
//先獲取導(dǎo)航分類接口,將結(jié)果進行返回,到調(diào)用函數(shù)的地方獲取
getNav(callback){
uni.request({
url:"https://ku.qingnian8.com/dataApi/news/navlist.php",
success:res=>{
callback(res)
}
})
},
//獲取文章數(shù)據(jù),將文章列表進行返回
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)
}
})
}
}
小結(jié): 我們通過封裝 方法 從而簡化代碼 讓代碼看起來更加清晰 ( 至少在看調(diào)用函數(shù)方面 會更加清晰 ), 但是并沒有很好解決回調(diào)地獄的問題
二 、什么是 Promise
promise是解決異步的方法,本質(zhì)上是一個構(gòu)造函數(shù),
可以用它實例化一個對象。對象身上有resolve、reject、all,原型上有then、catch方法。
promise對象有三種狀態(tài):
pending(初 識狀態(tài)/進行中)、resolved或fulfilled(成功)、rejected(失?。?/code>
下面我們直接打印一下 Promise
console.dir(Promise)
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-mVlwddYH-1675075189316)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20230130121411121.png)]
三 、將回調(diào)函數(shù)修改為 Promise 方案
2.0 版本 ( Promise 對象 )
.then 的鏈?zhǔn)秸{(diào)用函數(shù)
//promise鏈?zhǔn)秸{(diào)用
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)
})
函數(shù)封裝也需要進行修改
methods: {
//先獲取導(dǎo)航分類接口,將結(jié)果進行返回,到調(diào)用函數(shù)的地方獲取
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)
}
})
})
},
//獲取文章數(shù)據(jù),將文章列表進行返回
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)
}
})
})
}
看完上面兩段代碼 , 下面我們進行詳細的分析
很多初學(xué)者不是很清楚 .then 以及里面的一些參數(shù)等等
下面, 我們結(jié)合 上面的案例進行講解
首先, 在上面, 我們通過 console.log(Promise) 可以知道里面
包括了 then() catch() 等方法
所以我們要原來的調(diào)用函數(shù)的返回值 改成
返回 Promise 對象
在此之前我們需要對 // 對象 進行實例化
如下面:
getNav(callback){
return new Promise((resolve,reject)=>{
........
})
},
// 也可以下面這種寫法
getNav(callback){
// 實例化
let p = new Promise((resolve,reject)=>{
........
})
return p
},
有關(guān)于實例化 Promise 中的兩個參數(shù) (resolve,reject)
// 和 1.0 版本中 callblack 的作用差不多 主要起了回調(diào)數(shù)據(jù)的作用
// 不過, resolve 是表示運行成功的返回的數(shù)據(jù) reject是表示運行失敗返回的數(shù)據(jù)
getNav(callback){
return new Promise((resolve,reject)=>{
uni.request({
........,
success:res=>{
resolve(res)
},
fail:err=>{
reject(err)
}
})
})
},
四、await / async ES7的新規(guī)范,異步處理同步化
注意文章來源:http://www.zghlxwxcb.cn/news/detail-593782.html
// await / async 兩者需要一起使用, 才能起作用, 缺一不可
如果使用了await 沒有在函數(shù)中使用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)
}
關(guān)于封裝函數(shù)部分和 then的鏈?zhǔn)秸{(diào)用的封裝的代碼一樣
特別聲明: 本文章并非本人完全原創(chuàng), 只是對蝦米老師的筆記進行簡化以及添加一些自己的見解
還有就是 如果筆記有什么問題, 歡迎大家在評論區(qū)或者私信或者我們的交流群斧正。
我也是小白,希望和大家一起進步。
最后祝大家新年快樂!!!!
課程鏈接: https://www.bilibili.com/video/BV1XW4y1v7Md?share_source=copy_web文章來源地址http://www.zghlxwxcb.cn/news/detail-593782.html
到了這里,關(guān)于異步同步化( Promise 詳解)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!