当在原生微信小程序中进行 API 请求时,封装请求可以提高代码的可维护性和可扩展性。在本篇博客中,我们将一步步介绍如何进一步封装请求,并添加请求超时、拦截器和请求取消功能。
首先,我们创建一个用于发送 HTTP 请求的基本封装。在微信小程序中,我们使用 wx.request
发送请求,这里我们将它封装成一个 Promise 风格的函数:
// request.js
function request(url, method, data, header = {}) {
return new Promise((resolve, reject) => {
wx.request({
url: url,
method: method,
data: data,
header: {
'content-type': 'application/json', // 根据需求设置请求头
...header,
},
success: (res) => {
if (res.statusCode === 200) {
resolve(res.data);
} else {
reject(new Error('请求失败'));
}
},
fail: (err) => {
reject(err);
},
});
});
}
export function get(url, data = {}, header = {}) {
return request(url, 'GET', data, header);
}
export function post(url, data = {}, header = {}) {
return request(url, 'POST', data, header);
}
这段代码中,我们定义了两个函数 get
和 post
,分别用于发送 GET 和 POST 请求,并返回一个 Promise,以便在请求成功或失败时进行处理。
为了实现请求超时功能,我们可以使用 Promise 的 Promise.race
方法。我们创建一个新的 Promise,设置一个超时时间,然后将它与实际请求的 Promise 进行竞争。如果超时时间内请求未完成,我们可以取消请求并抛出一个超时错误。
// request.js
function requestWithTimeout(url, method, data, header = {}, timeout = 5000) {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
reject(new Error('请求超时'));
}, timeout);
wx.request({
url: url,
method: method,
data: data,
header: {
'content-type': 'application/json', // 根据需求设置请求头
...header,
},
success: (res) => {
clearTimeout(timer);
if (res.statusCode === 200) {
resolve(res.data);
} else {
reject(new Error('请求失败'));
}
},
fail: (err) => {
clearTimeout(timer);
reject(err);
},
});
});
}
export function getWithTimeout(url, data = {}, header = {}, timeout = 5000) {
return requestWithTimeout(url, 'GET', data, header, timeout);
}
export function postWithTimeout(url, data = {}, header = {}, timeout = 5000) {
return requestWithTimeout(url, 'POST', data, header, timeout);
}
拦截器允许我们在请求发出前和响应返回后进行一些自定义操作,例如添加请求头、记录日志或处理错误信息。我们可以通过使用函数链来实现这一功能。首先,我们创建两个空数组 requestInterceptors
和 responseInterceptors
,用于存储拦截器函数。然后,我们通过一个函数来添加拦截器,每个拦截器都是一个函数,接受 config
(请求配置)或 response
(响应对象)作为参数,并可以对它们进行修改。最后,在请求或响应时,我们通过遍历这些拦截器数组,依次执行它们。
// request.js
let requestInterceptors = [];
let responseInterceptors = [];
// 添加请求拦截器
export function addRequestInterceptor(interceptor) {
requestInterceptors.push(interceptor);
}
// 添加响应拦截器
export function addResponseInterceptor(interceptor) {
responseInterceptors.push(interceptor);
}
function executeInterceptors(interceptors, data) {
return interceptors.reduce((prevData, interceptor) => {
return interceptor(prevData);
}, data);
}
function request(url, method, data, header = {}, timeout = 5000) {
// ...
// 执行请求拦截器
config = executeInterceptors(requestInterceptors, config);
// ...
// 执行响应拦截器
responseData = executeInterceptors(responseInterceptors, responseData);
// ...
}
// ...
你可以使用 addRequestInterceptor
和 addResponseInterceptor
函数来添加自定义的拦截器,例如:
import { addRequestInterceptor, addResponseInterceptor } from './request';
// 添加请求拦截器
addRequestInterceptor((config) => {
// 在请求发出前进行一些操作,例如添加请求头
config.header['Authorization'] = 'Bearer ' + getToken();
return config;
});
// 添加响应拦截器
addResponseInterceptor((response) => {
// 在响应返回后进行一些操作,例如处理错误信息
if (response.statusCode !== 200) {
throw new Error('请求失败');
}
return response.data;
});
为了实现请求取消功能,我们可以使用 Axios 风格的取消令牌(CancelToken)。我们需要创建一个 CancelToken
对象,并将它包含在请求的配置中。然后,在需要取消请求的地方,我们可以调用 cancel
方法取消请求。
// request.js
let cancelToken = new wx.miniProgram.CancelToken();
function requestWithCancel(url, method, data, header = {}, timeout = 5000) {
return new Promise((resolve, reject) => {
wx.request({
url: url,
method: method,
data: data,
header: {
'content-type': 'application/json', // 根据需求设置请求头
...header,
},
cancelToken: cancelToken.token, // 设置取消令牌
success: (res) => {
if (res.statusCode === 200) {
resolve(res.data);
} else {
reject(new Error('请求失败'));
}
},
fail: (err) => {
reject(err);
},
});
});
}
// 取消请求
export function cancelRequest() {
cancelToken.cancel('请求取消');
}
进一步封装请求超时、拦截器和请求取消功能可以提高代码的灵活性和可维护性。以下是一个更完整的原生微信小程序 API 请求封装,包括这些功能:
javascript
Copy code
// api.js
// 创建一个取消请求的 CancelToken
const CancelToken = wx.miniProgram.CancelToken;
// 默认配置
const defaultConfig = {
baseURL: '', // 请求基础 URL
timeout: 5000, // 请求超时时间(毫秒)
};
// 请求拦截器
function requestInterceptor(config) {
// 在请求发送之前可以进行一些操作,例如添加请求头
config.header = {
'content-type': 'application/json',
...config.header,
};
return config;
}
// 响应拦截器
function responseInterceptor(response) {
// 在收到响应后可以进行一些操作,例如处理错误信息
if (response.statusCode !== 200) {
throw new Error('请求失败');
}
return response.data;
}
// 创建请求实例
const instance = wx.request.create({
timeout: defaultConfig.timeout,
header: {
'content-type': 'application/json',
},
});
// 发送请求的函数
function sendRequest(config) {
const { baseURL, timeout, ...restConfig } = { ...defaultConfig, ...config };
const { url, method, data, params, cancelToken, ...otherConfig } = restConfig;
// 合并请求 URL
const fullURL = `${baseURL}${url}`;
// 创建 CancelToken 实例
const source = CancelToken.source();
// 设置取消令牌
otherConfig.cancelToken = source.token;
// 发送请求
return instance({
url: fullURL,
method,
data,
params,
...otherConfig,
})
.then(responseInterceptor)
.catch((error) => {
if (wx.miniProgram.isCancel(error)) {
// 请求被取消
console.log('请求已取消');
} else {
// 请求发生错误
console.error('请求失败:', error);
}
throw error;
});
}
export { sendRequest, requestInterceptor, responseInterceptor };
在上面的代码中,添加了以下功能:
请求超时:可以通过设置 timeout 来指定请求超时时间,如果请求在规定时间内未完成,将会被取消。
请求拦截器和响应拦截器:可以在发送请求前和处理响应后进行一些自定义操作,例如添加请求头或处理错误信息。
请求取消:我们使用 Axios 的取消令牌(CancelToken)来支持请求取消功能。可以在请求配置中设置 cancelToken,然后在需要取消请求的地方调用 source.cancel()。
使用这个进一步封装的请求函数 sendRequest,你可以在项目中更加灵活地处理网络请求,同时在拦截器中进行自定义操作,以满足不同场景的需求。在小程序的页面中,导入 sendRequest 并使用它来发起请求即可。
以上就是原生微信小程序中进行 API 请求时感谢大家的阅读
如碰到其他的问题 可以私下我 一起探讨学习
如果对你有所帮助还请 点赞 收藏谢谢~!
关注收藏博客 作者会持续更新…