@slavmak2486/bx24ts
Version:
Library for bitrix24
115 lines (94 loc) • 3.83 kB
text/typescript
import {batchCmdElement, batchCmdElementParams} from './types/batchElement'
import { BX24 } from './BX24';
export class BatchHelper{
allRequest:[string, batchCmdElementParams][];
constructor(){
this.allRequest=[];
}
addToBatch(batchElement:batchCmdElement){
this.allRequest.push(...Object.entries(batchElement));
return this;
}
// Выявление зависимостей из $result
private findDependencies(totalBatch: [string, batchCmdElementParams][]) {
const dependencies: Record<string, string[]> = {};
for (const [key, val] of totalBatch) {
const params=Array.isArray(val)?val[1]:val.params;
const paramStr = JSON.stringify(params);
const matches = paramStr.match(/\$result\[([^\]]+)\]/g);
if (matches) {
const parents=matches.map(match => match.replace(/\$result\[|\]/g, ''));
parents.forEach(parent => {
if (!dependencies[parent]) {
dependencies[parent] = [];
}
dependencies[parent].push(key);
})
}
}
return dependencies;
}
getArrBatches(countInBatch=50):batchCmdElement[] {
const result: batchCmdElement[] = [];
const dependencies=this.findDependencies(this.allRequest);
let currentSize=0;
let currentChunk: batchCmdElement={};
const alradyInBatch: string[] = [];
const obj:batchCmdElement=this.allRequest.reduce(
(result, el:[string, batchCmdElementParams])=>Object.assign(result, {[el[0]]:el[1]}),
{}
);
for (const [key, value] of this.allRequest) {
if (alradyInBatch.includes(key)) continue;
if ((dependencies[key]?.length||0)>countInBatch){
throw new Error("BatchHelper: too many dependencies for "+key);
}
if (currentSize >= countInBatch || (currentSize+1+(dependencies[key]?.length||0)) > countInBatch) {
result.push(currentChunk);
currentChunk = {};
currentSize = 0;
}
alradyInBatch.push(key);
currentChunk[key] = value;
const deps=dependencies[key]||[];
for(const dep of deps){
alradyInBatch.push(dep);
currentChunk[dep] = obj[dep];
currentSize++;
}
currentSize++;
}
if (Object.keys(currentChunk).length > 0) {
result.push(currentChunk);
}
return result;
}
async runAll(bx24:BX24){
const totalResult={};
const arrBatch=this.getArrBatches();
for (const batch of arrBatch){
const ress=await bx24.callBatch(batch);
Object.assign(totalResult, ress);
}
return totalResult;
}
/**
* @param action - метод Bitrix24
* @param requestName - имя запроса в батче
* @param countRows - количество строк списочного метода
* @param params - дополнительные параметры
*/
getBatchForLength(action:string, requestName:string, countRows:number, params = {}) {
const countBatch = Math.ceil(countRows / (50 * 50))
for (let i = 0; i < countBatch; i++) {
for (let j = 0; j < 50; j++) {
if (50 * 50 * i + j * 50 >= countRows) {
break
}
const curParams = Object.assign({start:0}, params)
curParams['start'] = 50 * 50 * i + j * 50;
this.addToBatch({[requestName + `${i}-${j}`]:[action, curParams]});
}
}
}
}