|
|
Строка 2: |
Строка 2: |
|
| |
|
| = Сценарии = | | = Сценарии = |
|
| |
| == Изоляция сценариев ==
| |
|
| |
| Начиная с версии wb-rules 1.7, каждый файл сценария запускается в своём отдельном пространстве имён - '''контексте'''. Таким образом, каждый сценарий может определять
| |
| свои функции и глобальные переменные без риска изменить поведение других сценариев.
| |
|
| |
| === Пример ===
| |
| В качестве примера приведём два сценария, одновременно запускаемых в движке правил.
| |
| Каждый сценарий определяет глобальные переменные и функции.
| |
|
| |
| В предыдущих версиях wb-rules обращение к глобальной переменной, изменяемой в нескольких
| |
| файлах сценариев, может привести к неопределённому поведению. В версиях, начиная с 1.7,
| |
| поведение строго определено и такое же, как будто сценарий единственный в системе.
| |
|
| |
| В комментариях указан вывод команд log для ранних версий и для актуальной версии.
| |
|
| |
| '''Сценарий 1 (rules1.js)'''
| |
| <syntaxhighlight lang="js">
| |
| test1 = 42;
| |
|
| |
| setTimeout(function myFuncOne() {
| |
| log("myFuncOne called");
| |
| log("test1: {}, test2: {}", test1, test2);
| |
| // раньше: test1: [либо 42, либо 84], test2: Hello
| |
| // теперь: test1: 42, test2: (undefined)
| |
| // (будет выведена ошибка выполнения: ReferenceError: identifier 'test2' undefined)
| |
| }, 1000);
| |
| </syntaxhighlight>
| |
|
| |
| '''Сценарий 2 (rules2.js)'''
| |
| <syntaxhighlight lang="js">
| |
| test1 = 84;
| |
| test2 = "Hello";
| |
|
| |
| setTimeout(function myFuncTwo() {
| |
| log("myFuncTwo called");
| |
| log("test1: {}, test2: {}", test1, test2);
| |
| // раньше: test1: [либо 42, либо 84], test2: Hello
| |
| // теперь: test1: 84, test2: Hello
| |
| }, 1000);
| |
| </syntaxhighlight>
| |
|
| |
| === Примечание ===
| |
|
| |
| В предыдущих версиях wb-rules для изоляции правил рекомендовалось использовать замыкание, т.е.
| |
| оборачивание кода сценария в конструкцию:
| |
| <syntaxhighlight lang="js">
| |
| (function() {
| |
| // код сценария идёт здесь
| |
| })();
| |
| </syntaxhighlight>
| |
|
| |
| Начиная с версии 1.7, в подобной конструкции нет необходимости. Тем не менее, старые сценарии,
| |
| использующие эту конструкцию, продолжат работу без изменений в поведении.
| |
|
| |
| === Обходные пути ===
| |
|
| |
| Если в вашей системе использовалось общее глобальное пространство для хранения общих данных и функций,
| |
| есть несколько способов реализации такого поведения:
| |
|
| |
| ==== Использование модулей ====
| |
|
| |
| Можно написать модуль для организации взаимодействия. У модулей есть статическое хранилище,
| |
| общее для всех файлов, импортировавших модуль. (см. [[#Модули|Модули]])
| |
|
| |
| ==== Постоянное хранилище ====
| |
|
| |
| Для обмена данными также можно использовать глобальные постоянные хранилища (PersistentStorage).
| |
|
| |
| '''Внимание:''' при использовании глобальных постоянных хранилищ может произойти совпадение имён, в
| |
| этом случае возможно труднообнаруживаемое нарушение поведения.
| |
|
| |
| <syntaxhighlight lang="js">
| |
| var ps = new PersistentStorage("my-global-storage", {global: true});
| |
|
| |
| /// ...
| |
|
| |
| ps.myvar = "value"; // это значение доступно для всех пользователей хранилища с именем "my-global-storage"
| |
| </syntaxhighlight>
| |
|
| |
| ==== Прототип глобального объекта ====
| |
|
| |
| '''ВНИМАНИЕ:''' метод считается "грязным", т.к. все переменные и функции, опубликованные таким образом,
| |
| становятся доступными всем сценариям в системе. Старайтесь избегать этого способа. За неопределённое
| |
| поведение при использовании этого метода несёт ответственность сам программист.
| |
|
| |
| Глобальные объекты всех сценариев имеют общий объект-''прототип'', в котором определены стандартные функции
| |
| wb-rules (такие, как defineRule, setTimeout и т.д.). Через него можно передавать переменные или функции
| |
| в общую область видимости.
| |
|
| |
| <syntaxhighlight lang="js">
| |
| global.__proto__.myVar = 42; // теперь myVar - общая переменная для всех сценариев
| |
|
| |
| // из других сценариев к переменной можно обращаться так
| |
| log("shared myVar: {}", myVar);
| |
|
| |
| // или вот так, что чуть более аккуратно, т.к. однозначно показывает, где определена переменная
| |
| log("shared myVar: {}", global.__proto__.myVar);
| |
| </syntaxhighlight>
| |
|
| |
| Правило поиска переменной в первом случае будет выглядеть так:
| |
|
| |
| # Проверяем, есть ли myVar среди локальных переменных (определённой как var myVar = ...).
| |
| # Если нет, проверяем, есть ли myVar в глобальном объекте (определённой как myVar = ...).
| |
| # Если нет, проверяем, есть ли myVar в ''прототипе'' глобального объекта (определённой как global.__proto__.myVar).
| |
|
| |
| Поиск останавливается, как только переменная найдена.
| |
|
| |
| Таким образом, первый способ обращения будет работать только в том случае, если myVar не определена в верхних областях видимости.
| |
|
| |
| == Анонимные правила ==
| |
|
| |
| Теперь правила можно объявлять анонимно (без задания специального имени). Это позволит уменьшить путаницу и неочевидное
| |
| поведение системы при дублировании имён правил в одном скрипте.
| |
|
| |
| Уникальные имена для анонимных правил генерируются автоматически.
| |
|
| |
| Старый синтаксис (с явным заданием имени правила) продолжит работу без изменений.
| |
|
| |
| '''ВНИМАНИЕ:''' начиная с версии 1.7, при объявлении правил с одинаковыми
| |
| именами в одном файле теперь будет возвращаться ошибка.
| |
|
| |
| === Пример ===
| |
|
| |
| <syntaxhighlight lang="js">
| |
| defineRule({
| |
| whenChanged: "mydev/test",
| |
| then: function() {
| |
| log("mydev/test changed");
| |
| }
| |
| });
| |
| </syntaxhighlight>
| |
|
| |
| == Управление правилами ==
| |
|
| |
| В wb-rules 1.7 также появляется возможность управлять выполнением правил. Теперь функция defineRule() возвращает идентификатор
| |
| созданного правила (аналогично setTimeout()/setInterval() ), который можно использовать позже для:
| |
|
| |
| * выключения/включения отработки правила;
| |
| * принудительного запуска тела правила.
| |
|
| |
| По умолчанию, все правила включены.
| |
|
| |
| === Пример ===
| |
|
| |
| <syntaxhighlight lang="js">
| |
| var myRule = defineRule({
| |
| whenChanged: "mydev/test",
| |
| then: function() {
| |
| log("mydev/test changed");
| |
| }
| |
| });
| |
|
| |
| // ...
| |
|
| |
| disableRule(myRule); // отключить проверку и выполнение правила
| |
| enableRule(myRule); // разрешить выполнение правила
| |
|
| |
| runRule(myRule); // принудительно запустить тело правила (функцию then)
| |
| // на текущий момент не поддерживается передача аргументов в then
| |
| </syntaxhighlight>
| |
|
| |
| == Постоянное хранилище данных == | | == Постоянное хранилище данных == |
|
| |
|