1.前言
總結(jié)前后端交互的幾種方式的時(shí)候,突然想起來之前小程序用promise封裝ajax,簡要記錄如下
這幾天閑來無事又梳理了下promise
2.常規(guī)封裝
function getApi(url, data, successCB) {
wx.showLoading({
title: '加載中',
})
wx.request({
url: baseUrl + url,
data,
header: {
'content-type': 'application/json' // 默認(rèn)值
},
success: (res) => {
if (res.code = 200) {
// 回調(diào)到組件 ,數(shù)據(jù)給他
successCB && successCB(res.data)
} else {
wx.showToast({
title: '服務(wù)器錯(cuò)誤',
icon: 'error',
duration: 2000
})
}
},
fail: (err) => {
wx.showToast({
title: '服務(wù)器錯(cuò)誤',
icon: 'error',
duration: 2000
})
console.log("錯(cuò)誤信息:", err);
},
complete(res) {
// console.log("complete",res);
wx.hideLoading()
// wx.stopPullDownRefresh()
}
})
}
3.promise封裝
const getApi = (url, data) => {
wx.showLoading({
title: '加載中',
mask: true
})
// Promise 承諾:處理異步回調(diào) 同意 拒絕
return new Promise(function (resolve, reject) {
// 只能走一個(gè) 要么同意 要么拒絕
// resolve() 回調(diào)then()
// reject() 回調(diào)catch()
wx.request({
url: baseUrl + url,
data,
header: {
'content-type': 'application/json' // 默認(rèn)值
},
success: (res) => {
resolve(res.data)
},
fail: () => {
wx.showToast({
title: '服務(wù)器錯(cuò)誤',
icon: 'error',
duration: 2000
})
reject("服務(wù)器錯(cuò)誤,請稍后重試");
},
complete(res) {
// console.log("complete",res);
wx.hideLoading()
// wx.stopPullDownRefresh()
}
})
})
}
4. 調(diào)用
var api = require('../../utils/api');
var shopUrl = ""
var data = {}
api.getApi(shopUrl,data).then(()=>{
//處理數(shù)據(jù)
}).catch(()=>{
//異常處理
wx.showToast({
title: '服務(wù)器錯(cuò)誤',
icon: 'error',
duration: 2000
})
})
5. why 為什么需要 promise
誕生背景,解決了哪些問題
- js中代碼都是單線程 異步執(zhí)行的.實(shí)現(xiàn)異步的方式主要是 回調(diào)函數(shù)
2
.Promise
是異步編程的一種解決方案,比傳統(tǒng)的解決方案更合理和更強(qiáng)大破婆。它由社區(qū)最早提出和實(shí)現(xiàn)涮坐,ES6
將其寫進(jìn)了語言標(biāo)準(zhǔn)辽俗,統(tǒng)一了用法,原生提供了Promise
對象
6. 基礎(chǔ)概念
簡單說就是一個(gè)容器游昼,里面保存著某個(gè)未來才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果凿掂。
從語法上說灯荧,
Promise
是一個(gè)對象,從它可以獲取異步操作的消息陕截。Promise
提供統(tǒng)一的 API驳棱,各種異步操作都可以用同樣的方法進(jìn)行處
可以理解為 君子一諾千金,答應(yīng)的事情,等我這邊忙完,一定會(huì)給你個(gè)答復(fù),不管拒絕還是同意.
7. 核心要點(diǎn)
1.對象的狀態(tài)不受外界影響。
Promise
對象代表一個(gè)異步操作农曲,有三種狀態(tài):pending(進(jìn)行中)
社搅、fulfilled(已成功)
和rejected(已失敗)
乳规。只有異步操作的結(jié)果形葬,可以決定當(dāng)前是哪一種狀態(tài),任何其他操作都無法改變這個(gè)狀態(tài)暮的。這也是Promise這個(gè)名字的由來
它的英語意思就是
“承諾”
笙以,表示其他手段無法改變。
2. 一旦狀態(tài)改變冻辩,就不會(huì)再變猖腕,任何時(shí)候都可以得到這個(gè)結(jié)果。
Promise
對象的狀態(tài)改變恨闪,只有兩種可能:
從pending
變?yōu)?code>fulfilled和
從pending
變?yōu)?code>rejected倘感。
只要這兩種情況發(fā)生,狀態(tài)就凝固了咙咽,不會(huì)再變了老玛,會(huì)一直保持這個(gè)結(jié)果,這時(shí)就稱為
resolved(已定型
)钧敞。如果改變已經(jīng)發(fā)生了蜡豹,你再對Promise
對象添加回調(diào)函數(shù),也會(huì)立即得到這個(gè)結(jié)果犁享。
這與
事件(Event)
完全不同余素,事件的特點(diǎn)是,如果你錯(cuò)過了它炊昆,再去監(jiān)聽桨吊,是得不到結(jié)果的
8. 缺點(diǎn)
1.無法取消
Promise
,一旦新建它就會(huì)立即執(zhí)行威根,無法中途取消。
2.如果不設(shè)置回調(diào)函數(shù)视乐,Promise
內(nèi)部拋出的錯(cuò)誤洛搀,不會(huì)反應(yīng)到外部。
3.當(dāng)處于pending
狀態(tài)時(shí)佑淀,無法得知目前進(jìn)展到哪一個(gè)階段(剛剛開始還是即將完成)
9. 案例
隨機(jī)數(shù)大于4 你贏了 武林盟主
比多久不清楚,所有用定期模擬,間隔時(shí)間也是變量
var test = (resolve, reject) => {
var randomNum = Math.random() * 10
console.log("隨機(jī)是:", randomNum);
// 比武什么時(shí)候結(jié)束 是不確定 ,用定時(shí)器模擬這個(gè)不確定
setTimeout(() => {
if (randomNum > 4) {
resolve("周潤發(fā) 賭王 贏了")
} else {
reject("周潤發(fā) 問鼎賭王 失敗")
}
}, 1000 * randomNum)
}
外界并不關(guān)心你們這場 比武的過程,只關(guān)注結(jié)果
10. then 你贏的結(jié)果
函數(shù)執(zhí)行成功 告訴
Promise
對象:執(zhí)行then
then
方法返回的是一個(gè)新的Promise實(shí)例(注意留美,不是原來那個(gè)Promise實(shí)例
)。
因此可以采用鏈?zhǔn)綄懛ㄉ烊校?code>then方法后面再調(diào)用另一個(gè)then
方法谎砾。
var p1 = new Promise(test)
var p2 = p1.then(res => {
console.log("成功:", res);
})
Promise
實(shí)例具有then
方法,也就是說捧颅,then
方法是定義在原型對象Promise.prototype
上的景图。
它的作用是為
Promise
實(shí)例添加狀態(tài)改變時(shí)的回調(diào)函數(shù)
。前面說過碉哑,then方
法的第一個(gè)參數(shù)是resolved
狀態(tài)的回調(diào)函數(shù)挚币,第二個(gè)參數(shù)是rejected
狀態(tài)的回調(diào)函數(shù),它們都是可選的扣典。
11. catch 你輸?shù)慕Y(jié)果
函數(shù)執(zhí)行
失敗
時(shí)妆毕,我們告訴Promise
對象: 執(zhí)行catch
方法
var p3 = p2.catch(err=>{
console.log("失敗:",err)
})
Promise.prototype.catch()方法是.then(null, rejection)或.then(undefined, rejection)的別名,用于指定發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)
12. finally 不管輸贏 都會(huì)走
finally()
方法用于指定不管Promise
對象最后狀態(tài)如何贮尖,都會(huì)執(zhí)行
的操作笛粘。該方法是 ES2018 引入標(biāo)準(zhǔn)的。
var p4 = p3.finally(()=>{
console.log("都會(huì)執(zhí)行")
})
13. 鏈?zhǔn)綄懛?/h1>
new Promise((resolve, reject) => {
var randomNum = Math.random() * 10
console.log("隨機(jī)是:", randomNum);
// 比武什么時(shí)候結(jié)束 是不確定 ,用定時(shí)器模擬這個(gè)不確定
setTimeout(() => {
if (randomNum > 4) {
resolve("周潤發(fā) 賭王 贏了")
} else {
reject("周潤發(fā) 問鼎賭王 失敗")
}
}, 1000 * randomNum)
}).then(res=>{
console.log("成功:",res);
}).catch(err=>{
console.log("失敗:",err);
})
14.原生ajax封裝
這里只是簡單的例子 ,具體的 請求參數(shù) 還需要另做
<button onclick="sendBtn()">發(fā)送</button>
<script>
function sendBtn() {
ajax("GET", "./data.json").then(res => {
console.log("res:", res)
}).catch(err => console.log(err))
}
// ajax函數(shù)將返回Promise對象:
function ajax(method, url, data) {
var request = new XMLHttpRequest();
return new Promise(function (resolve, reject) {
request.onreadystatechange = function () {
if (request.readyState === 4) {
if (request.status === 200) {
resolve(JSON.parse(request.responseText))
} else {
reject(request.status);
}
}
};
request.open(method, url);
request.send(data);
});
}
</script>
15. 總結(jié)
Promise最大的好處是:
1.在異步執(zhí)行的流程中远舅, 把執(zhí)行代碼和處理結(jié)果的代碼清晰地分離了
- 將異步操作以同步操作的流程表達(dá)出來闰蛔,避免了層層嵌套的回調(diào)函數(shù)
3.Promise對象提供統(tǒng)一的接口,使得控制異步操作更加容易
參考資料
初心
我所有的文章都只是基于入門图柏,初步的了解序六;是自己的知識(shí)體系梳理;
如果能幫助到有緣人,非常的榮幸,一切都是為了部落
的崛起
共勉
new Promise((resolve, reject) => {
var randomNum = Math.random() * 10
console.log("隨機(jī)是:", randomNum);
// 比武什么時(shí)候結(jié)束 是不確定 ,用定時(shí)器模擬這個(gè)不確定
setTimeout(() => {
if (randomNum > 4) {
resolve("周潤發(fā) 賭王 贏了")
} else {
reject("周潤發(fā) 問鼎賭王 失敗")
}
}, 1000 * randomNum)
}).then(res=>{
console.log("成功:",res);
}).catch(err=>{
console.log("失敗:",err);
})
這里只是簡單的例子 ,具體的 請求參數(shù) 還需要另做
<button onclick="sendBtn()">發(fā)送</button>
<script>
function sendBtn() {
ajax("GET", "./data.json").then(res => {
console.log("res:", res)
}).catch(err => console.log(err))
}
// ajax函數(shù)將返回Promise對象:
function ajax(method, url, data) {
var request = new XMLHttpRequest();
return new Promise(function (resolve, reject) {
request.onreadystatechange = function () {
if (request.readyState === 4) {
if (request.status === 200) {
resolve(JSON.parse(request.responseText))
} else {
reject(request.status);
}
}
};
request.open(method, url);
request.send(data);
});
}
</script>
1.在異步執(zhí)行的流程中远舅, 把執(zhí)行代碼和處理結(jié)果的代碼清晰地分離了
- 將異步操作以同步操作的流程表達(dá)出來闰蛔,避免了層層嵌套的回調(diào)函數(shù)
3.Promise對象提供統(tǒng)一的接口,使得控制異步操作更加容易
部落
的崛起