@lcap/nasl
Version:
NetEase Application Specific Language
102 lines • 3.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.batchApiCall = exports.httpRequestConcurrently = void 0;
const nasl_utils_1 = require("@lcap/nasl-utils");
const url_1 = require("url");
// 浏览器端不支持 undici,必须要屏蔽掉
/// #if process.env.BUILD_TARGET === 'node'
const undici_1 = require("undici");
const agent = new undici_1.Agent({
connections: 200,
pipelining: 2,
autoSelectFamily: true,
autoSelectFamilyAttemptTimeout: 30000,
headersTimeout: 120000,
bodyTimeout: 120000,
keepAliveTimeout: 120000,
});
/// #endif
function parseAxiosUrl(axios, data) {
const baseUrl = (axios.defaults.baseURL ?? data.baseURL ?? '').replace(/\/+$/, '');
const url = data.url.replace(/^\/+/, '');
const fullUrl = `${baseUrl}/${url}`;
return (0, url_1.parse)(fullUrl);
}
/** 高并发请求 */
async function httpRequestConcurrently(axios, data) {
/// #if process.env.BUILD_TARGET === 'node'
if (nasl_utils_1.isNode && agent && process.env.NODE_ENV !== 'testing') {
const headers = {
'User-Agent': 'Undici/1.0',
...axios.defaults.headers.common,
...axios.defaults.headers[data.method.toLowerCase()],
...data.headers,
};
for (const key of Object.keys(axios.defaults.headers)) {
if (typeof axios.defaults.headers[key] === 'string') {
headers[key] = axios.defaults.headers[key];
}
}
// 默认使用 json 格式
if (!headers['Content-Type']) {
headers['Content-Type'] = 'application/json';
}
const url = parseAxiosUrl(axios, data);
const requestConfig = {
origin: `${url.protocol}//${url.host}`,
path: url.pathname,
headers,
method: data.method.toUpperCase(),
body: JSON.stringify(data.data),
};
const response = await agent.request(requestConfig);
// 请求参数插入返回状态
response.request = requestConfig;
if (response.statusCode !== 200) {
throw response;
}
const text = await response.body.text();
const result = JSON.parse(text);
// 请求结果插入返回状态
response.result = result;
if (result.code !== 200) {
throw response;
}
return result;
}
else
/// #endif
{
return axios(data).then(({ data }) => data);
}
}
exports.httpRequestConcurrently = httpRequestConcurrently;
/**
* 分批调用接口并合并结果
* @param {AxiosInstance} http - 请求实例
* @param {Array} payloads - 需要处理的完整数据列表
* @param {Function} apiCallFn - 接口调用函数,接收数据数组作为参数并返回 Promise
* @param {any} extraParams - 额外参数
* @param {number} batchSize - 每批次数据量,默认250
* @returns {Promise<Array>} - 所有批次处理结果合并后的数组
*/
async function batchApiCall(http, payloads, apiCallFn, extraParams, batchSize = 250) {
// 如果数据量小于等于批次大小,直接调用接口
if (payloads.length <= batchSize) {
return apiCallFn(http, payloads, extraParams);
}
// 分批数据
const batches = [];
for (let i = 0; i < payloads.length; i += batchSize) {
batches.push(payloads.slice(i, i + batchSize));
}
// 并行调用所有批次
const results = await Promise.all(batches.map((batch) => {
return apiCallFn(http, batch, extraParams);
}));
return results.reduce((acc, curr) => {
return acc.concat(curr);
}, []);
}
exports.batchApiCall = batchApiCall;
//# sourceMappingURL=utils.js.map