Когда .bind () запустится? - PullRequest
0 голосов
/ 06 июня 2018

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

let configData = initConfig();  // Initialize configuration data from file

setInterval(taskA.bind(null, configData), TASK_A_WAIT);  // Task using config data

setInterval(taskB.bind(null, configData), TASK_B_WAIT);  // Task using config data

setInterval(taskC.bind(null, configData), TASK_C_WAIT);  // Task using config data

setInterval(refreshConfig.bind(null, (error, result) => {    // Update config data
    if (error) handleError(error);
    else configData = result;
}), CONFIG_REFRESH_WAIT);

Цель состоит в том, чтобы данные конфигурации обновлялись с интервалом с использованием последних setInterval(), так что первые три setInterval() всегда имеют самые последние данные для работы.Но сработает ли это?

В семантике javascript будет ли вышеприведенное фактически связывать функцию с последним объектом configData заново с каждым интервалом?Когда в таком сценарии происходят привязки?

Ответы [ 2 ]

0 голосов
/ 06 июня 2018

Поскольку bind() не заключен в другую функцию, он выполняется синхронно на месте.

Функции задач связаны с оригиналом configData.Если он переназначен с configData = result, это не влияет на связанные функции.

Функции задач должны быть обернуты функциями для переназначения configData:

setInterval(() => { taskA(configData) }, TASK_A_WAIT)

Еще один вариант, который будет работатьс bind - для сохранения той же ссылки для configData объекта, это будет работать, только если начальный configData является объектом:

setInterval(refreshConfig.bind(null, (error, result) => {
  ... 
  Object.assign(configData, result);
}), CONFIG_REFRESH_WAIT);

Если есть вероятность, что configData уже имеет свойства, которые возможноне будет переопределено, сначала должно быть очищено .

0 голосов
/ 06 июня 2018

Если вы хотите, чтобы задачи продолжали ссылаться на живую версию configData, вы должны передавать анонимную функцию-обертку для каждого из вызовов для setInterval(), например, которая ограничивает ссылку на символическую переменную, а не привязывает оригиналссылка на объект для каждой функции:

let configData = initConfig();  // Initialize configuration data from file

setInterval(() => taskA(configData), TASK_A_WAIT);  // Task using config data

setInterval(() => taskB(configData), TASK_B_WAIT);  // Task using config data

setInterval(() => taskC(configData), TASK_C_WAIT);  // Task using config data

setInterval(refreshConfig.bind(null, (error, result) => {    // Update config data
    if (error) handleError(error);
    else configData = result;
}), CONFIG_REFRESH_WAIT);

В качестве альтернативы, если вы не хотите, чтобы ссылка изменялась, и вы знаете, что структура конфигурации никогда не изменится, вы можете предпочесть configData a * 1007.* ссылаться и использовать Object.assign() для создания мелкой копии ключей result, перезаписывая каждый ключ в configData новыми значениями в result:

const configData = initConfig();  // Initialize configuration data from file

setInterval(taskA.bind(null, configData), TASK_A_WAIT);  // Task using config data

setInterval(taskB.bind(null, configData), TASK_B_WAIT);  // Task using config data

setInterval(taskC.bind(null, configData), TASK_C_WAIT);  // Task using config data

setInterval(refreshConfig.bind(null, (error, result) => {    // Update config data
    if (error) handleError(error);
    else Object.assign(configData, result);
}), CONFIG_REFRESH_WAIT);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...