Разрешить другим функциям JavaScript (в том числе из других файлов) «подключаться» к моей функции - PullRequest
0 голосов
/ 21 июня 2019

Мне кажется, что я переосмысливаю эту концепцию, но я застрял на ней. Может ли JavaScript разрешать другим функциям (из одного и того же или разных файлов JS) подключаться к функции?

Чтобы уточнить, если я создаю массив в функции, которую я пишу, можно ли разрешить другим JS-файлам подключаться к нему для изменения этого массива до его анализа? Или мне нужно было бы создать какую-то систему для управления всеми «хуками»? Я хотел бы избежать использования глобальной переменной окна, если это возможно, но это будет работать .

Вот пример

Ради аргумента давайте предположим, что они выполняются в порядке, в котором я их перечислил (игнорируйте условие гонки, которое я создал здесь).

main.js

var animals = ['cat', 'dog'];
animals = hookIntoThis(animals); //Allow other functions or files to add/modify animals to the array here
console.log(animals); //--> "cat", "dog", "elephant"

hookIntoThis() на самом деле не является ссылкой на что-либо - это просто место, где я бы хотел, чтобы другие функции / файлы (если они существуют) модифицировали массив.

other.js

function addMoreAnimals(animals){ //This would somehow listen for that hook from main.js
    animals.push('elephant');
    animals.push('lion');

    return animals;
}

whatever.js

function noLions(animals){ //This would also hook into that function from main.js to modify the array
    if ( animals.indexOf('lion') >= 0 ){
        animals.splice(animals.indexOf('lion'), 1); //Just for the sake of example
    }

    return animals;
}

Сначала я думал, что пользовательское событие / слушатель DOM будет работать, но это (насколько я знаю) вещь односторонняя. Я мог бы вызвать и даже передать массив животных в событие DOM, но если я не использую глобальную переменную окна, я не смогу получить никаких данных назад .

Я прошу прощения, если это слишком простая концепция и / или дублирующий вопрос. Я довольно долго искал, прежде чем опубликовать это.

1 Ответ

0 голосов
/ 21 июня 2019

Пользовательский прослушиватель событий является правильным, я думаю, если main не знает, какие другие модули будут изменять animals.

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

// main.js
let modifiableAnimals = ['cat', 'dog'];
window.addEventListener('customHook', ({ detail: modifyFn }) => {
  modifiableAnimals = modifyFn(modifiableAnimals);
});
Promise.resolve()
  .then(() => {
    console.log(modifiableAnimals);
  });

// other.js
window.dispatchEvent(
  new CustomEvent(
    'customHook',
    {
      detail: (animals) => {
        animals.push('elephant');
        animals.push('lion');
        return animals;
      }
    }
  )
);

// whatever.js
window.dispatchEvent(
  new CustomEvent(
    'customHook',
    {
      detail: (animals) => {
        if ( animals.indexOf('lion') >= 0 ){
          animals.splice(animals.indexOf('lion'), 1); //Just for the sake of example
        }
        return animals;
      }
    }
  )
);

Если вы знаете, что существующий массив будет только мутирован (и не должен быть переназначен), вы можете упростить его:бит:

// main.js
const modifiableAnimals = ['cat', 'dog'];
window.addEventListener('customHook', ({ detail: modifyFn }) => {
  modifyFn(modifiableAnimals);
});
Promise.resolve()
  .then(() => {
    console.log(modifiableAnimals);
  });

// other.js
window.dispatchEvent(
  new CustomEvent(
    'customHook',
    {
      detail: (animals) => {
        animals.push('elephant');
        animals.push('lion');
      }
    }
  )
);

// whatever.js
window.dispatchEvent(
  new CustomEvent(
    'customHook',
    {
      detail: (animals) => {
        if ( animals.indexOf('lion') >= 0 ){
          animals.splice(animals.indexOf('lion'), 1); //Just for the sake of example
        }
      }
    }
  )
);

Хотя это все еще немного странно, ИМО.Если возможно, я бы подумал о том, чтобы иметь интерфейс else с main.js и другими файлами, и вместо этого вызывал бы main.js функции с обработчиками:

// main.js
function changeAnimals(...changeFns) {
  const modifiableAnimals = ['cat', 'dog'];
  changeFns.forEach(fn => fn(modifiableAnimals));
  console.log(modifiableAnimals);
}

// other.js
const pushElephantAndLion = (animals) => {
  animals.push('elephant');
  animals.push('lion');
};

// whatever.js
const removeOneLion = (animals) => {
  if ( animals.indexOf('lion') >= 0 ){
    animals.splice(animals.indexOf('lion'), 1); //Just for the sake of example
  }
};

// *actual* main code:
changeAnimals(pushElephantAndLion, removeOneLion);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...