/* * ✨ 常用辅助工具类函数 ✨ * */ import req from '@/request' /** * 自动取消请求构造器 * @description 创建一个带有自动取消功能的请求函数,该函数会在新请求发起之前自动取消前一个未完成的请求。 * @param {Object | string} config - 请求配置对象或URL字符串,配置对象可参考axios请求配置项。 * @returns {Function} 返回一个用于发起请求的函数,并附带:取消或查看请求状态等功能。 * @example * const request = createAutoCancelRequest('/api/data') * request({ id: 123 }).then(response => console.log(response)) * console.log(request.isRequestPending()) // 是否有未完成的请求 * request.cancel() // 取消当前请求 * * // 也可以单独给接口函数指定一个唯一标识符 * // 以避免同一实例接口函数被用于不同位置调用,造成取消冲突及误取消。 * request({ id: 123 },'default').then(response => console.log(response)) * console.log(request.isRequestPending('default')) * request.cancel(callback ,'default') * */ export function createAutoCancelRequest(config) { // 参数归一化处理 let newConfig = { method: 'GET', baseURL: window.context.portal, ...(typeof config === 'string' ? {url: config} : config) } // 根据请求方法决定参数存储的 key ('data' 或 'params') const _methodsKey = ['POST', 'PUT', 'PATCH'].includes( newConfig.method?.toUpperCase() ) ? 'data' : 'params' // 使用 Map 存储请求的中断控制器 const _abortControllerMap = new Map() /** * 发起新的请求 * @param {Object} [reqData={}] - 请求的参数数据 * @param {string} [identifier='default'] - 请求标识符,用于区分不同的请求 * @returns {Promise} - 返回请求的结果 */ const sendRequest = async (reqData = {}, identifier = 'default') => { // 取消之前同标识符的请求 if (_abortControllerMap.has(identifier)) _abortControllerMap.get(identifier).abort() // 创建并存储新的中断控制器 const abortController = new AbortController() _abortControllerMap.set(identifier, abortController) try { // 发起请求 const {data} = await req.$http({ ...newConfig, [_methodsKey]: reqData, signal: abortController.signal }) // 请求成功完成后移除对应的中断控制器 _abortControllerMap.delete(identifier) return data } catch (err) { // 错误情况下不移除中断控制器,便于后续处理 throw err } } /** * 检查是否有未完成的请求 * @param {string} [identifier='default'] - 请求标识符 * @returns {boolean} - 如果请求正在进行且未被中断,返回 true */ sendRequest.isRequestPending = (identifier = 'default') => { const controller = _abortControllerMap.get(identifier) return controller && !controller.signal.aborted } /** * 取消指定标识符的请求 * @param {Function} [callback] - 取消请求后的回调函数 * @param {string} [identifier='default'] - 请求标识符 */ sendRequest.cancel = (callback, identifier = 'default') => { if (sendRequest.isRequestPending(identifier)) _abortControllerMap.get(identifier).abort() callback && callback() } return sendRequest } /** * 判断一个值是否非空。 * 空的定义包括:null、undefined、空字符串、空数组和空对象。 * * @param {*} value - 需要判断的值。 * @returns {boolean} 如果值非空,则返回 true;否则返回 false。 */ export function isNotEmpty(value) { // 检查是否为 null 或 undefined if (value === null || value === undefined) { return false } // 检查字符串是否为空(去除空白字符后) if (typeof value === 'string') { if (value.trim() === '') { return false } } // 检查数组是否为空 if (Array.isArray(value)) { if (value.length === 0) { return false } } // 检查对象是否为空 if (typeof value === 'object' && !Array.isArray(value)) { // 获取对象的所有可枚举属性名 const keys = Object.keys(value) if (keys.length === 0) { return false } } return true }