Публикация

Универсальная функция вызова метода скрипта без подключения этого скрипта

У меня часто возникает ситуация, когда мне нужно вызвать какую-либо функцию только при определенных условиях и не хочеться подключать тот скрипт, в котором она находиться. Известно, что с каждым подключаемым скриптом быстродействие работы CRM затормаживается (подгружаются в память все подключаемые скрипты).

Я использую следующую функцию в тех случаях, когда мне не всегда нужно вызывать какой-либо метод из другого скрипта в текущем скрипте:

function ExecuteScriptMethod(ScriptName, MethodName) {
        var Script = GetSingleItemByCode(ScriptName);
        var CodeObject = Script.ScriptControl.CodeObject;
        var Arg;
        var Args = new Array();
        var Code = 'return CodeObject.'+MethodName+'(';
        for (var i = 2; i arguments.length; i++) {
                if (i > 2) {
                        Code += ',';
                }
                Args.push(arguments[i]);
                Code += 'Args['+(Args.length-1)+']';
        }
        Code += ');';
        var CustomFunction = new Function('CodeObject', 'Args', Code);
        return CustomFunction(CodeObject, Args);
}

Первым аргументом в этой функции является название скрипта, который содержит нужную нам функцию.
Второй аргумент содержит, собственно, название самой вызываемой функции.
Все последующие аргументы (третий, четвертый, ... бесконечность) являются аргументами для вызываемой функции, указанной во втором аргументе.

Эту функцию я разместил в скрипт scr_Utils, который уже задействован в большинстве других скриптов. Для новых скриптов мне достаточно будет подключить скрипт scr_Utils в новый скрипт, если я планирую использовать эту функцию.

Пример использования:

var CurrencyID = Dataset('CurrencyID');
var RateDate = GetLocalDateTime();
RateDate = ExtractDate(RateDate);
var Rate = ExecuteScriptMethod('scr_CurrencyUtils', 'GetRate',  CurrencyID, TodayDate, 1, true);

В этом примере я вызвал функцию получения курса валюты без подключения скрипта scr_CurrencyUtils. Таким образом можно ускорить работу системы, исключая из подключения те скрипты, использование которых не является регулярным в том скрипте, к которому они подключены.

Например, можно вынести каждое отдельное действие раздела в отдельный скрипт и использовать этот скрипт только при необходимости.

Нравится

Поделиться

3 комментария

При таком подходе при каждом вызове функции будет происходить работа по её подготовке, что может повлиять на производительность негативно, если функция вызывается в цикле.

А можно просто возвращать ссылку на функцию, которую потом многократно использовать как обычную?

return CustomFunction;

Иногда это очень удобно. Такой механизм используется в базовых версиях для отложенной загрузки нечасто используемых функций

"Зверев Александр" написал:А можно просто возвращать ссылку на функцию, которую потом многократно использовать как обычную?

Можно это сделать так:

function ExecuteScriptMethod(ScriptName, MethodName) {
	var Script = GetSingleItemByCode(ScriptName);
	var CodeObject = Script.ScriptControl.CodeObject;
	var Arg;
	var Args = new Array();
	var FuncDict;
	var CustomFunction;
	if (Assigned(Connector.Attributes('FuncDict'))) {
		FuncDict = Connector.Attributes('FuncDict');
	} else {
		FuncDict = GetNewDictionary();
	}
	if (FuncDict.Exists(ScriptName+'_'+MethodName)) {
		CustomFunction = FuncDict(ScriptName+'_'+MethodName);
		for (var i = 2; i < arguments.length; i++) {
			Args.push(arguments[i]);
		}
	} else {
		var Code = 'return CodeObject.'+MethodName+'(';
		for (var i = 2; i < arguments.length; i++) {
			if (i > 2) {
				Code += ',';
			}
			Args.push(arguments[i]);
			Code += 'Args['+(Args.length-1)+']';
		}
		Code += ');';
		CustomFunction = new Function('CodeObject', 'Args', Code);
		FuncDict(ScriptName+'_'+MethodName) = CustomFunction;
		Connector.Attributes('FuncDict') = FuncDict;
	}
	return CustomFunction(CodeObject, Args);
}
Показать все комментарии