Выразительный JavaScript (Хавербеке) - страница 112

, в случае когда никакие зависимости не нужно грузить.

>function define(depNames, moduleFunction) {

>  var myMod = currentMod;

>  var deps = depNames.map(getModule);


>  deps.forEach(function(mod) {

>    if (!mod.loaded)

>      mod.onLoad.push(whenDepsLoaded);

>  });


>  function whenDepsLoaded() {

>    if (!deps.every(function(m) { return m.loaded; }))

>      return;


>    var args = deps.map(function(m) { return m.exports; });

>    var exports = moduleFunction.apply(null, args);

>    if (myMod) {

>      myMod.exports = exports;

>      myMod.loaded = true;

>      myMod.onLoad.every(function(f) { f(); });

>    }

>  }

>  whenDepsLoaded();

>}

Когда все зависимости доступны, >whenDepsLoaded вызывает функцию, содержащую модуль, передавая в виде аргументов интерфейсы зависимостей.

Первое, что делает >define, это сохраняет значение >currentMod, которое было у него при вызове, в переменной >myMod. Вспомните, что >getModule прямо перед исполнением кода модуля сохранил соответствующий объект модуля в >currentMod. Это позволяет >whenDepsLoaded хранить возвращаемое значение функции модуля в свойстве >exports этого модуля, установить свойство >loaded модуля в >true, и вызвать все функции, ждавшие загрузки модуля.

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

Настоящая реализация AMD гораздо умнее подходит к превращению имён модулей в URL и более надёжна, чем показано в примере. Проект RequireJS предоставляет популярную реализацию такого стиля загрузчика модулей.

Разработка интерфейса

Разработка интерфейсов – один из самых тонких моментов в программировании. Любую нетривиальную функциональность можно реализовать множеством способов. Поиск работающего способа требует проницательности и предусмотрительности.

Лучший способ познать значимость хорошего интерфейса – использовать много интерфейсов. Некоторые будут плохие, некоторые хорошие. Опыт покажет вам, что работает, а что – нет. Никогда не принимайте как должное плохой интерфейс. Исправьте его, или заключите в другой интерфейс, который лучше вам подходит.

Предсказуемость

Если программист может предсказать, как работает ваш интерфейс, ему не придётся часто отвлекаться и смотреть подсказку по его использованию. Постарайтесь следовать общепринятым соглашениям. Если есть модуль или часть языка JavaScript, которая делает что-то похожее на то, что вы пытаетесь реализовать – будет неплохо, если ваш интерфейс будет напоминать существующий. Таким образом, он будет привычен для людей, знакомых с существующим интерфейсом.