前幾天收到一個(gè)需求调衰,就是在網(wǎng)絡(luò)請(qǐng)求超時(shí)時(shí),彈出一個(gè)toast告知用戶“網(wǎng)絡(luò)請(qǐng)求超時(shí)自阱,請(qǐng)稍后重試嚎莉!”。當(dāng)接到這個(gè)需求時(shí)沛豌,一開(kāi)始并沒(méi)有覺(jué)得有多麻煩趋箩,直接在fetch請(qǐng)求時(shí)設(shè)置一下timeout屬性就行了。于是乎就去React Native的開(kāi)發(fā)文檔中去找加派,可結(jié)果卻讓人“很難過(guò)”叫确,居然沒(méi)有找到,心里不免嘀咕“又掉到坑里面了”芍锦。
好吧竹勉,既然沒(méi)有timeout屬性就只能自己去想辦法解決了。經(jīng)過(guò)一段時(shí)間的思考娄琉,初步確定了三種解決方案:
- 通過(guò)和原生的交互來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求超時(shí)的功能饶米;
- 把fetch重新封裝一下,加上timeout的功能车胡,參考博文檬输;
- 使用其他的網(wǎng)絡(luò)庫(kù),文檔中說(shuō)React Native中已經(jīng)內(nèi)置了XMLHttpRequest API(也就是俗稱(chēng)的ajax);
在項(xiàng)目中我選擇了第二種方法匈棘,具體的實(shí)現(xiàn)如下:
//Http.js
export default fetchers = {
post:(url, body = {}) => {
return _fetch(fetch_promise(url, body = {}), 60000);
}
}
function _fetch(fetch_promise, timeout) {
var abort_fn = null;
var abort_promise = new Promise((resolve, reject) => {
abort_fn = function() {
reject('abort promise');
};
});
var abortable_promise = Promise.race([
fetch_promise,
abort_promise
]);
setTimeout(function(){
abort_fn();
}, timeout);
return abortable_promise;
}
function fetch_promise(url, body = {}) {
return new Promise((resolve, reject) => {
fetch(url,{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8',
},
}).then((response) => {
return response.json();
}).then((jsonData) => {
resolve(jsonData);
}).catch((err) => {
reject(err);//這里可以使用resolve(err),將錯(cuò)誤信息傳回去
if (err.message === 'Network request failed'){
console.log('網(wǎng)絡(luò)出錯(cuò)');
} else if (err === 'abort promise'){
console.log('請(qǐng)求超時(shí)');
}
})
})
}
/*
* 此巧妙之處在于Promise.race()的使用
*/
這是目前項(xiàng)目中初步解決網(wǎng)絡(luò)超時(shí)的方法丧慈,第一種和第三種方案還沒(méi)有來(lái)得及去實(shí)現(xiàn),后期如果有時(shí)間實(shí)現(xiàn)會(huì)在此后加上主卫。如果發(fā)現(xiàn)有需要修改的地方或是好的建議逃默,也可以留言告知,大家相互交流相互提高嘛簇搅!