Подскажите про метод forEach

Здравствуйте. Подскажите как работаем метод forEach.
Понимаю что метод пробегает по массиву и запускает функцию для каждого элемента массива.
Не понятно как часто он это делает? Только при запуске wb-rules или при каждом просмотре правил.
Например такой код

var buttons = {
    "wb-mr6cv3_246/Input 2 Single Press Counter" : "toggle", //выключатель 2
    "wb-mr6cv3_246/Input 2 Long Press Counter" : "dim",
    "wb-mr6cv3_246/Input 2 Double Press Counter" : "off",
};

var lamp = [
            {
            name: "LED strip 163/2",
            actionControl: "wb-led_163/Channel 2",
            btn: [
                "wb-mr6cv3_246/Input 2 Double Press Counter",
                "wb-mr6cv3_246/Input 2 Single Press Counter",
                "wb-mr6cv3_246/Input 2 Long Press Counter",
                 ],
            control_Brightness: true,
            dim_interval: 100,
            min_Brightness: 20, 
            brightness_night_mode: 50,
            motion_sensor: {
                            name: "wb-msw-v4_195",
                            set_timer: 2, // уставка таймера с.
                            threshold_motion_sensor: 500, // пороговое значение датчика движения
                            threshold_Illuminance_sensor: 10000, // пороговое значение датчика освещенности
                           },
            functions: [actionlamp,
                       motion_sensor],
            },
         ];

lamp.forEach(function(item) {
item.functions.forEach(function(i){
i(item)})
});

function actionlamp(par){
// логика обработки нажатий выключателей
};

function motion_sensor (par) {
// логика работы датчика движение
};

c циклом в цикле будет излишне нагружать процессор? Или лучше все функции прописать явно в коде?

Здравствуйте

Метод forEach выполняет цикл для каждого элемента массива только в момент, когда он вызывается в коде. Он не запускается автоматически или постоянно. В вашем случае forEach выполняется однократно при выполнении кода в момент запуска правила wb-rules. Т.е. скрипт запускается каждый раз только при запуске службы wb-rules.

Ваш вызов lamp.forEach(...) запускается при каждом выполнении скрипта или правила. Это не периодический процесс — вызов происходит только тогда, когда правило или сценарий активируются - только при запуске службы wb-rules.

Если этот код (вызов lamp.forEach) запускается, например, в defineRule, он выполнится каждый раз, когда сработает соответствующее правило.


Ваш код вызывает две вложенные итерации:

  1. Первая итерация: пробегает по всем элементам массива lamp.
  2. Вторая итерация: пробегает по массиву functions для каждого элемента lamp и вызывает каждую функцию с текущим элементом.

Нагрузка зависит от:

  1. Количества элементов в массиве lamp.
  2. Количества функций в массиве functions.
  3. Сложности самих функций (actionlamp и motion_sensor).

Прямое написание функций без цикла может выглядеть так:

actionlamp(lamp[0]);
motion_sensor(lamp[0]);
actionlamp(lamp[1]);
motion_sensor(lamp[1]);

Но такой подход:

  1. Увеличивает размер кода.
  2. Усложняет масштабирование (если добавляется новый элемент в lamp).

Использование forEach или аналогичных циклов гораздо удобнее для обработки массива объектов.

У вас остались какие-либо вопросы?

Желание использовать forEach мной, как раз обусловлено созданием более короткого и лаконичного кода.
Я правильно понял что цикл при запускe wb-rules создаст все функции типа:

actionlamp(lamp[0]);
motion_sensor(lamp[0]);
actionlamp(lamp[1]);
motion_sensor(lamp[1]) 

И будет держать их в памяти, и если сработает правило (например defineRule) относящееся только к:

actionlamp(lamp[0]);

То вызовется только эта функция, а не
Запустится весь цикл заново.
Извиняюсь за глупые вопросы, но не хочется увеличивать нагрузку и время выполнения кода из за “кривого” кода.
Количество элементов в массиве lamp будет около 100, функций в массиве functions 1-4.

Грубо говоря - да. Давайте попробую пояснить, как это связано с нагрузкой и структурой программы:

  1. Код с forEach:
  • Вся логика forEach выполняется только при явном вызове. Это означает, что цикл не “создаёт функции” или “держит их в памяти”. Он просто проходит по массиву в момент выполнения и вызывает указанные функции.
  • Если правило, например defineRule, запускает этот forEach, то выполняется весь цикл, а не только функция, относящаяся к одному элементу.
  1. Код без forEach (явные вызовы):
  • Когда вы явно вызываете actionlamp(lamp[0]);, вы точно указываете, какую функцию вызвать и для какого элемента. Это может быть полезно для оптимизации, если вам нужно обращаться к конкретному объекту.
  1. Нагрузка от цикла forEach:
  • Даже если у вас в массиве lamp 100 элементов, а в массиве functions для каждого элемента 1-4 функции, современный контроллер справится с такой нагрузкой, если функции не содержат сложных вычислений.
  • Вызов всех функций для 100 объектов (например, 400 вызовов) за одну итерацию может занять миллисекунды, что незначительно для большинства задач.
1 Like

Большое спасибо за развёрнутый ответ.