Как работают загрузчики AMD под капотом?

Итак, я уже некоторое время использую require.js, но понял, что на самом деле не знаю, как это работает внутри. Там написано, что это загрузчик AMD.

Я понимаю, что CommonJS является синхронным, что означает, что он блокирует выполнение других кодов во время загрузки. С другой стороны, AMD асинхронна. Вот тут я запутался.

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

  1. Разве это не синхронно, когда сначала нужно загрузить эти три зависимости?
  2. Означает ли это, что AMD загружает a, b, c асинхронно, затем проверяет, загружены ли эти файлы (не заботится о порядке), а затем выполняет обратный вызов?
define("name",["a","b","c"], function(a,b,c){

});

person Moon    schedule 24.08.2012    source источник


Ответы (2)


Как вы знаете, «AMD» (определение асинхронного модуля (AMD)) — это особый API. Существует множество совместимых с AMD «загрузчиков», включая RequireJS, curl.js и Dojo (среди прочих).

Подобно тому, как такие фреймворки, как JQuery и Dojo, предоставляют вам API поверх необработанного Javascript; программа, использующая AMD:

1) требуется совместимая с AMD библиотека .js,

2) требует определенных «правил» и «условий» программирования, и

3) В конечном итоге находится «поверх» Javascript, который работает на вашем «движке Javascript» (будь то IE, Chrome, Firefox — что угодно).

Вот пара ссылок, которые мне пригодились:

PS: Чтобы ответить на ваш непосредственный вопрос, в последней ссылке есть небольшое обсуждение о «require ()» и «динамически загруженных зависимостях».

person paulsm4    schedule 24.08.2012
comment
Благодарим вас за вклад. Я все еще немного запутался в том, как загрузчики CJS и AMD загружают зависимости. - person Moon; 25.08.2012
comment
Что это значит, когда загрузчики AMD говорят «Асинхронный»? - person Moon; 25.08.2012
comment
ОК: AMD на самом деле больше, чем просто асинхронность. И да, обычный JS тоже можно охарактеризовать как асинхронный. Постарайтесь не зацикливаться на этом слове. Ключевое преимущество AMD заключается в том, как идентифицировать (и, следовательно, разумно загружать) зависимости в контексте. Эта ссылка может помочь: github.com/jrburke/requirejs/wiki/. Но опять же, это гораздо больше, чем просто загрузка. Ссылки, которые я привел, должны помочь... - person paulsm4; 25.08.2012

Так как я написал загрузчик AMD, то постараюсь ответить на вопросы напрямую:

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

Javascript по определению является однопоточным. Это означает, что все, что вы запускаете в нем, всегда выполняется последовательно. Единственное, что вы можете сделать в браузере, это включить скрипты, используя параметр «async» в теге скрипта, что сделает порядок загрузки скриптов неопределенным (асинхронным). После выполнения сценария он будет единственным, выполняющимся в данный момент времени.

Означает ли это, что AMD загружает a, b, c асинхронно, затем проверяет, загружены ли эти файлы (не заботится о порядке), а затем выполняет обратный вызов?

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

Затем каждый раз, когда вызывается define(), загрузчик AMD проверяет, удовлетворяется ли уже текущий список зависимостей для этого определения. Если это так, он немедленно вызовет текущий обратный вызов, а после этого проверит, можно ли также вызвать какой-либо из ранее зарегистрированных обратных вызовов определения (поскольку все их зависимости были удовлетворены). Если еще не все зависимости для этого обратного вызова удовлетворены, обратный вызов добавляется в очередь для последующего разрешения.

Это в конечном итоге приводит к тому, что все обратные вызовы вызываются в правильном порядке зависимостей, независимо от порядка, в котором сценарии были загружены/выполнены в первую очередь.

person BuGless    schedule 18.09.2018