js使用Promise實現(xiàn)簡單的Ajax緩存
業(yè)務場景
在不少業(yè)務場景下,我們需要實現(xiàn)簡單的請求緩存(即某個請求只發(fā)起一次請求),例如上傳 Token 的獲取、獲取配置的接口等。
這些接口可以通過 Promise 實現(xiàn)簡單的緩存并能夠控制更新,而不需要另外引入緩存層。
示范代碼
用七牛上傳作例子,一般我們會把七牛上傳封裝為一個單獨的 Upload 組件,外部只需要調(diào)用組件,而 token 的獲取封裝到組件內(nèi)部實現(xiàn)。
//Upload.vue
let fetchToken = null;
export default {
data() {
return {
token: ''
};
},
methods: {
async upload() {
try {
// ...
}
catch(err) {
alert(err.message);
this.refreshToken();
}
},
refreshToken() {
fetchToken = null;
this.fetchToken();
},
fetchToken() {
if (!fetchToken) {
fetchToken = request.get('/api/qiniu/token');
}
try {
this.token = await fetchToken;
}
catch(err) {
console.error(err);
}
}
},
created() {
this.fetchToken();
}
};
上面是一個簡單的緩存上傳 token 的例子,并且會在上傳失敗時刷新 token。
與直接緩存 Token 的值比較,緩存請求有什么好處?
// 緩存值的代碼
export default {
methods: {
fetchToken() {
if (!fetchToken) {
fetchToken = await request.get('/api/qiniu/token');
}
try {
this.token = fetchToken;
}
catch(err) {
console.error(err);
}
}
}
}
一個比較常見的 Upload 組件 的應用場景,在一個頁面里同時使用多次該組件。
<template> <div class="upload1"><upload /></div> <div class="upload2"><upload /></div> </template>
就上面的代碼例子,如果使用緩存值的方法,那么頁面一打開就會請求兩次獲取 Token 接口。
繼續(xù)完善 Upload 組件
//Upload.vue
let fetchToken = null;
export default {
methods: {
async upload() {
try {
this.fetchToken();
const token = await fetchToken;
// ...
} catch (err) {
alert(err.message);
this.refreshToken();
}
},
refreshToken() {
fetchToken = null;
this.fetchToken();
},
fetchToken() {
if (!fetchToken) {
fetchToken = request.get('/api/qiniu/token');
}
}
},
created() {
this.fetchToken();
}
};
為了防止多個 Upload 組件 token 不同步問題,不再通過this.token保存 token,而是每次都等待 fetchToken resolved,保證獲取到的 token 一定是最新的。
當然,這里還有很多需要優(yōu)化,例如失敗后的重試、判斷是 401 失敗才刷新 token、設置錯誤時間、定時刷新等等,但總體思路就是上面代碼所展示的內(nèi)容。
另外再介紹一個經(jīng)典應用場景
const fetchConfig = (() => {
let configRequest = null;
return () => {
if (!configRequest) {
configRequest = Promise.all([services.customer.config1, services.customer.config2])
.then(([data1, data2]) => {
return { data1, data2 };
})
.catch(err => {
configRequest = null;
return Promise.reject(err);
});
}
return configRequest;
};
})();
export default {
async beforeRouteEnter(to, from, next) {
try {
// 配置信息僅需要成功請求一次
const [data, config] = await Promise.all([services.customer.getInfo(), fetchConfig()]);
next(vm => {
vm.data = data;
vm.config = config;
vm.init();
};
} catch (err) {
next(err);
}
}
};
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JS實現(xiàn)的Object數(shù)組去重功能示例【數(shù)組成員為Object對象】
這篇文章主要介紹了JS實現(xiàn)的Object數(shù)組去重功能,可實現(xiàn)針對數(shù)組成員為Object對象的去重復功能,涉及javascript數(shù)組元素遍歷、屬性判斷等相關(guān)操作技巧,需要的朋友可以參考下2019-02-02
JavaScript/Js腳本處理html元素的自定義屬性解析(親測兼容Firefox與IE)
這篇文章主要是對JavaScript/Js腳本處理html元素的自定義屬性解析(親測兼容Firefox與IE)進行了詳細的介紹,需要的朋友可以過來參考下,希望對大家有所幫助2013-11-11

