12 063
правки
(Подготовка страницы к переводу) |
(Отметить эту версию для перевода) |
||
Строка 1: | Строка 1: | ||
<languages/> | <languages/> | ||
<translate> | <translate> | ||
<!--T:1--> | |||
В обновлённом движке правил wb-rules присутствует ряд важных нововведений, касающихся логики написания сценариев. | В обновлённом движке правил wb-rules присутствует ряд важных нововведений, касающихся логики написания сценариев. | ||
= Сценарии = | = Сценарии = <!--T:2--> | ||
== Изоляция сценариев == | == Изоляция сценариев == <!--T:3--> | ||
<!--T:4--> | |||
Начиная с версии wb-rules 1.7, локальные переменные и функции, обьявленные в файле сценария не видны в других сценариях. | Начиная с версии wb-rules 1.7, локальные переменные и функции, обьявленные в файле сценария не видны в других сценариях. | ||
Таким образом, каждый сценарий может определять свои функции и переменные без риска изменить поведение других сценариев. | Таким образом, каждый сценарий может определять свои функции и переменные без риска изменить поведение других сценариев. | ||
=== Пример === | === Пример === <!--T:5--> | ||
<!--T:6--> | |||
В качестве примера приведём два сценария, одновременно запускаемых в движке правил. | В качестве примера приведём два сценария, одновременно запускаемых в движке правил. | ||
Каждый сценарий определяет переменные и функции. | Каждый сценарий определяет переменные и функции. | ||
<!--T:7--> | |||
В предыдущих версиях wb-rules обращение к переменной, изменяемой в нескольких | В предыдущих версиях wb-rules обращение к переменной, изменяемой в нескольких | ||
файлах сценариев, может привести к неопределённому поведению. В версиях, начиная с 1.7, | файлах сценариев, может привести к неопределённому поведению. В версиях, начиная с 1.7, | ||
поведение строго определено и такое же, как будто сценарий единственный в системе. | поведение строго определено и такое же, как будто сценарий единственный в системе. | ||
<!--T:8--> | |||
В комментариях указан вывод команд log для ранних версий и для актуальной версии. Обратите внимание на var перед переменными. | В комментариях указан вывод команд log для ранних версий и для актуальной версии. Обратите внимание на var перед переменными. | ||
<!--T:9--> | |||
'''Сценарий 1 (rules1.js)''' | '''Сценарий 1 (rules1.js)''' | ||
<syntaxhighlight lang="js"> | <syntaxhighlight lang="js"> | ||
var test1 = 42; | var test1 = 42; | ||
<!--T:10--> | |||
setInterval(function myFuncOne() { | setInterval(function myFuncOne() { | ||
log("myFuncOne called"); | log("myFuncOne called"); | ||
Строка 34: | Строка 41: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<!--T:11--> | |||
'''Сценарий 2 (rules2.js)''' | '''Сценарий 2 (rules2.js)''' | ||
<syntaxhighlight lang="js"> | <syntaxhighlight lang="js"> | ||
Строка 39: | Строка 47: | ||
var test2 = "Hello"; | var test2 = "Hello"; | ||
<!--T:12--> | |||
setInterval(function myFuncTwo() { | setInterval(function myFuncTwo() { | ||
log("myFuncTwo called"); | log("myFuncTwo called"); | ||
Строка 46: | Строка 55: | ||
<!--T:13--> | |||
Было: | Было: | ||
<pre> | <pre> | ||
Строка 54: | Строка 64: | ||
2019-01-05 17:29:50test2: Hello | 2019-01-05 17:29:50test2: Hello | ||
<!--T:14--> | |||
</pre> | </pre> | ||
<!--T:15--> | |||
Стало: | Стало: | ||
<pre> | <pre> | ||
Строка 71: | Строка 83: | ||
=== Примечание === | === Примечание === <!--T:16--> | ||
<!--T:17--> | |||
В предыдущих версиях wb-rules для изоляции правил рекомендовалось использовать замыкание, т.е. | В предыдущих версиях wb-rules для изоляции правил рекомендовалось использовать замыкание, т.е. | ||
оборачивание кода сценария в конструкцию: | оборачивание кода сценария в конструкцию: | ||
Строка 81: | Строка 94: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<!--T:18--> | |||
Начиная с версии 1.7, в подобной конструкции обычно нет необходимости. Тем не менее, старые сценарии, | Начиная с версии 1.7, в подобной конструкции обычно нет необходимости. Тем не менее, старые сценарии, | ||
использующие эту конструкцию, продолжат работу без изменений в поведении. | использующие эту конструкцию, продолжат работу без изменений в поведении. | ||
=== Обходные пути === | === Обходные пути === <!--T:19--> | ||
<!--T:20--> | |||
Если в вашей системе использовалось общее глобальное пространство для хранения общих данных и функций, | Если в вашей системе использовалось общее глобальное пространство для хранения общих данных и функций, | ||
есть несколько способов реализации такого поведения: | есть несколько способов реализации такого поведения: | ||
==== Постоянное хранилище ==== | ==== Постоянное хранилище ==== <!--T:21--> | ||
<!--T:22--> | |||
Для обмена данными также можно использовать глобальные постоянные хранилища (PersistentStorage). | Для обмена данными также можно использовать глобальные постоянные хранилища (PersistentStorage). | ||
<!--T:23--> | |||
'''Внимание:''' при использовании глобальных постоянных хранилищ может произойти совпадение имён, в | '''Внимание:''' при использовании глобальных постоянных хранилищ может произойти совпадение имён, в | ||
этом случае возможно труднообнаруживаемое нарушение поведения. | этом случае возможно труднообнаруживаемое нарушение поведения. | ||
<!--T:24--> | |||
<syntaxhighlight lang="js"> | <syntaxhighlight lang="js"> | ||
var ps = new PersistentStorage("my-global-storage", {global: true}); | var ps = new PersistentStorage("my-global-storage", {global: true}); | ||
<!--T:25--> | |||
/// ... | /// ... | ||
<!--T:26--> | |||
ps.myvar = "value"; // это значение доступно для всех пользователей хранилища с именем "my-global-storage" | ps.myvar = "value"; // это значение доступно для всех пользователей хранилища с именем "my-global-storage" | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== Прототип глобального объекта ==== | ==== Прототип глобального объекта ==== <!--T:27--> | ||
<!--T:28--> | |||
'''ВНИМАНИЕ:''' метод считается "грязным", т.к. все переменные и функции, опубликованные таким образом, | '''ВНИМАНИЕ:''' метод считается "грязным", т.к. все переменные и функции, опубликованные таким образом, | ||
становятся доступными всем сценариям в системе. Старайтесь избегать этого способа. За неопределённое | становятся доступными всем сценариям в системе. Старайтесь избегать этого способа. За неопределённое | ||
поведение при использовании этого метода несёт ответственность сам программист. | поведение при использовании этого метода несёт ответственность сам программист. | ||
<!--T:29--> | |||
Глобальные объекты всех сценариев имеют общий объект-''прототип'', в котором определены стандартные функции | Глобальные объекты всех сценариев имеют общий объект-''прототип'', в котором определены стандартные функции | ||
wb-rules (такие, как defineRule, setTimeout и т.д.). Через него можно передавать переменные или функции | wb-rules (такие, как defineRule, setTimeout и т.д.). Через него можно передавать переменные или функции | ||
в общую область видимости. | в общую область видимости. | ||
<!--T:30--> | |||
<syntaxhighlight lang="js"> | <syntaxhighlight lang="js"> | ||
global.__proto__.myVar = 42; // теперь myVar - общая переменная для всех сценариев | global.__proto__.myVar = 42; // теперь myVar - общая переменная для всех сценариев | ||
<!--T:31--> | |||
// из других сценариев к переменной можно обращаться так | // из других сценариев к переменной можно обращаться так | ||
log("shared myVar: {}", myVar); | log("shared myVar: {}", myVar); | ||
<!--T:32--> | |||
// или вот так, что чуть более аккуратно, т.к. однозначно показывает, где определена переменная | // или вот так, что чуть более аккуратно, т.к. однозначно показывает, где определена переменная | ||
log("shared myVar: {}", global.__proto__.myVar); | log("shared myVar: {}", global.__proto__.myVar); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<!--T:33--> | |||
Правило поиска переменной в первом случае будет выглядеть так: | Правило поиска переменной в первом случае будет выглядеть так: | ||
<!--T:34--> | |||
# Проверяем, есть ли myVar среди локальных переменных (определённой как var myVar = ...). | # Проверяем, есть ли myVar среди локальных переменных (определённой как var myVar = ...). | ||
# Если нет, проверяем, есть ли myVar в глобальном объекте (определённой как myVar = ...). | # Если нет, проверяем, есть ли myVar в глобальном объекте (определённой как myVar = ...). | ||
# Если нет, проверяем, есть ли myVar в ''прототипе'' глобального объекта (определённой как global.__proto__.myVar). | # Если нет, проверяем, есть ли myVar в ''прототипе'' глобального объекта (определённой как global.__proto__.myVar). | ||
<!--T:35--> | |||
Поиск останавливается, как только переменная найдена. | Поиск останавливается, как только переменная найдена. | ||
<!--T:36--> | |||
Таким образом, первый способ обращения будет работать только в том случае, если myVar не определена в верхних областях видимости. | Таким образом, первый способ обращения будет работать только в том случае, если myVar не определена в верхних областях видимости. | ||
== Постоянное хранилище данных == | == Постоянное хранилище данных == <!--T:37--> | ||
<!--T:38--> | |||
В wb-rules 1.7 добавлена поддержка постоянных хранилищ. По сути, это объекты, значения в которых будут сохраняться | В wb-rules 1.7 добавлена поддержка постоянных хранилищ. По сути, это объекты, значения в которых будут сохраняться | ||
даже при потере питания контроллера. Такие хранилища удобно использовать для хранения состояний или конфигурации. | даже при потере питания контроллера. Такие хранилища удобно использовать для хранения состояний или конфигурации. | ||
<!--T:39--> | |||
<syntaxhighlight lang="js"> | <syntaxhighlight lang="js"> | ||
var ps = new PersistentStorage("my-storage", { global: true }); | var ps = new PersistentStorage("my-storage", { global: true }); | ||
<!--T:40--> | |||
ps.key = "Hello World"; | ps.key = "Hello World"; | ||
log(ps.key); | log(ps.key); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<!--T:41--> | |||
Поддерживаются только глобальные хранилища, т.е. видимые по одному и тому же имени из всех файлов сценариев. | Поддерживаются только глобальные хранилища, т.е. видимые по одному и тому же имени из всех файлов сценариев. | ||
== Виртуальные устройства == | == Виртуальные устройства == <!--T:42--> | ||
<!--T:43--> | |||
В предыдущих версиях wb-rules значения контролов виртуальных устройств хранились только в MQTT retained, что не очень надёжно (в случае | В предыдущих версиях wb-rules значения контролов виртуальных устройств хранились только в MQTT retained, что не очень надёжно (в случае | ||
потери питания данные могли быть легко утеряны). Начиная с версии 2.0, эти значения сохраняются также в специальное хранилище в постоянной | потери питания данные могли быть легко утеряны). Начиная с версии 2.0, эти значения сохраняются также в специальное хранилище в постоянной | ||
памяти и восстанавливаются при загрузке сценария. | памяти и восстанавливаются при загрузке сценария. | ||
<!--T:44--> | |||
Если необходимо каждый раз при перезагрузке скрипта восстанавливать строго определённое значение (т.е. не восстанавливать предыдущее сохранённое), | Если необходимо каждый раз при перезагрузке скрипта восстанавливать строго определённое значение (т.е. не восстанавливать предыдущее сохранённое), | ||
можно добавить в описание контрола поле forceDefault: | можно добавить в описание контрола поле forceDefault: | ||
<!--T:45--> | |||
<syntaxhighlight lang="js"> | <syntaxhighlight lang="js"> | ||
defineVirtualDevice("vdev", { | defineVirtualDevice("vdev", { |
правки