Лучшая практика для контекстного режима во время выполнения в JS

У меня есть веб-приложение на основе Apache. PHP, JS и JQuery. Все работает отлично.

На стороне клиента в JS/jquery есть небольшая библиотека, предлагающая несколько общих методов обработки списков. В прошлом я использовал обратные вызовы для решения тех немногих проблем, когда эти методы должны были вести себя немного иначе. Таким образом, я могу повторно использовать методы, такие как обработка списков, обработка диалогов и прочее для разных частей приложения. Однако в последнее время количество обратных вызовов, которые мне пришлось пройти, когда я вошел в библиотеку, выросло, и я пытаюсь изменить дизайн:

Вместо того, чтобы указывать все обратные вызовы в качестве аргументов функции, я создал в библиотеке объект центрального каталога. Каждый модуль приложения регистрирует свой собственный вариант обратных вызовов в этот каталог после инициализации. Во время выполнения методы ищут требуемые обратные вызовы в этом каталоге, а не ожидают, что это указано в их списке аргументов. Это очищает вещи довольно много.

Однако у меня есть одна вещь, от которой я до сих пор не могу избавиться: мне требуется один аргумент (я называю это контекстом, режим может быть другим термином), который используется методами для поиска требуемого обратного вызова в каталоге. Этот контекст должен быть передан всем методам. Конечно, лучше, чем всевозможные обратные вызовы, указанные везде, но мне интересно, смогу ли я избавиться от этого последнего. Но где мне указать этот контекст, если не в качестве аргумента метода? Я довольно новичок в JS и jquery, поэтому мне не удалось найти подход к этому. Очевидно, я не хочу использовать глобальные переменные, и, честно говоря, я сомневаюсь, что в любом случае я могу просто сохранить контекст в одной переменной, поскольку из-за всех обработчиков событий и внешних воздействий методы могут вызываться в разных контекстах одновременно время или, по крайней мере, чередование. Так что я думаю, мне нужно что-то ближе к стеку функций. Может быть, я могу просто поместить объект контекста в стек и прочитать его из слоев библиотеки, которые нужно знать? Объект будет удален, когда я снова покину библиотеку. Конечно, существуют и другие подходы.

Вот так много опытных программистов, которые, безусловно, могут дать новичку краткую подсказку, отправную точку, которая приводит к идее, как это реализовать. Как это обычно делается?


Я пытался некоторое время, исследуя arguments.callee.caller иерархия. Я подумал, что, возможно, я мог бы установить член-прототип внутри вызывающей функции, а затем, когда выполнение пошагово пошло вниз, я мог бы просто проходить вверх по стеку вызовов, пока не найду вызывающего, содержащего такое свойство, и использую это значение как контекст. Однако я также видел продолжающиеся дискуссии, которые раскрывают две вещи: 1.) arguments.callee кажется обесценившимся и 2.) он кажется действительно дорогим. Так что это не пойдет.

Я также читал об альтернативе Function.caller (которая, кажется, не является устаревшей и намного более эффективной, однако до сих пор мне не удавалось исследовать этот путь...


Как написано в настоящее время, передача контекста / режима просто работает путем указания дополнительного аргумента в вызовах функций. Он содержит уникальную строку, которая используется в качестве ключа при просмотре каталога. Итак, как-то так (не скопировано, а написано в качестве примитивного примера):

<!-- callbacks -->
callback_inner_task_base:function(arg1,arg2){
  // do something with args
}
callback_inner_task_spec:function(arg1,arg2){
  // do something with args
}

<!-- catalog -->
Catalog.Callback:function(context,slot){
  // some plausibility checks...
  return Catalog[context][slot];
}
Catalog.base.slot=callback_inner_task_base;
Catalog.spec.slot=callback_inner_task_spec;

<!-- callee -->
do_something:function(arg1,arg2,context){
  ...
  // callback as taken from the catalog
  Catalog.Callback(callback,'inner_task')(arg1,arg2);
  ...
}

<!-- caller -->
init:function(...){
  ...
  do_something('thing-1',thing-2','base');
  do_something('thing-1',thing-2','spec');
  ...
}

1 ответ

Но где мне указать этот контекст, если не в качестве аргумента метода?

  • Используйте свойство функции, например Catalog.Callback.context
  • Используйте монаду
Другие вопросы по тегам