本文参考了Fetch进阶指南
缘起
fetch网络请求没有timeout机制,也没有about机制。
而日常开发过程中,必定要对请求超时做处理,也要及时终止不需要的网络请求。
所以,就需要自己封装fetch来实现。
实现
Promise.race(promise1,promise2,...) 方法返回一个Promise对象, 只要参数中任意一个Promise 被 resolve 或者 reject 后, 外部的Promise 就会以相同的值被 resolve 或者 reject.
import React, {Component} from 'react';
/**
* 使用Promise封装Fetch,具有网络超时、请求终止的功能
*/
class NetUtil extends Component {
static baseUrl = "http://xxxx:81/api/";
static token = '';
/**
* post请求
* url : 请求地址
* data : 参数(Json对象)
* callback : 回调函数
* */
static fetch_request(url, method, params = '') {
let header = {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8',
'accesstoken': NetUtil.token,
}
let promise = null;
if (params == '') {
promise = new Promise((resolve, reject) => {
fetch(NetUtil.baseUrl + url, {method: method, headers: header})
.then(response => response.json())
.then(responseData => resolve(responseData))
.then(err => reject(err))
})
} else {
promise = new Promise((resolve, reject) => {
fetch(NetUtil.baseUrl + url, {method: method, headers: header, body: JSON.stringify(params)})
.then(response => response.json())
.then(responseData => resolve(responseData))
.then(err => reject(err))
})
}
return NetUtil.warp_fetch(promise);
}
/**
* 创建两个promise对象,一个负责网络请求,另一个负责计时,如果超过指定时间,就会先回调计时的promise,代表网络超时。
* @param {Promise} fetch_promise fetch请求返回的Promise
* @param {number} [timeout=10000] 单位:毫秒,这里设置默认超时时间为10秒
* @return 返回Promise
*/
static warp_fetch(fetch_promise, timeout = 10000) {
let timeout_fn = null;
let abort = null;
//创建一个超时promise
let timeout_promise = new Promise(function (resolve, reject) {
timeout_fn = function () {
reject('网络请求超时');
};
});
//创建一个终止promise
let abort_promise = new Promise(function (resolve, reject) {
abort = function () {
reject('请求终止');
};
});
//竞赛
let abortable_promise = Promise.race([
fetch_promise,
timeout_promise,
abort_promise,
]);
//计时
setTimeout(timeout_fn, timeout);
//终止
abortable_promise.abort = abort;
return abortable_promise;
}
}
export default NetUtil;