Ответ 1
Поскольку мой комментарий, похоже, ответил на эту проблему, я думал, что напишу его формально.
При использовании Require.js вам нужно подумать о зависимостях между модулями. В некотором смысле, это та же проблема, что и вы не использовали. Предположим, что у вас есть два файла: A.js и B.js, которые определяют функцию "A" и функцию "B" соответственно:
// A.js
window.A = function() {
// ...
};
// B.js
window.B = function() {
// ...
};
Вы можете добавить эти файлы в любом порядке на свою страницу, и ваш код будет работать. Но что, если ваше определение "B" зависит от определения "A":
// B.js
window.B = window.A || function() {
// ...
};
Теперь, внезапный порядок имеет значение: вы должны включить свой файл B.js после файла A.js, иначе код B не будет работать. И если ваш A.js также зависит от вашего B.js...
// A.js
window.A = window.B || function() {
// ...
};
Тогда ваш код будет смертельно ошибочным, потому что B зависит от A и A зависит от B, и сначала нужно определить. Это то, что известно как "круговая зависимость".
Требовать имеет ту же проблему, только ее легче пропустить, потому что требует от вас абстрактных материалов. В конце дня, хотя Требование (являющееся кодом JavaScript) должно выполняться последовательно, что означает, что он должен определить ваши модули в некотором порядке. Если ваш модуль A зависит от модуля B, а B зависит от A, у вас будет такая же проблема с круговой зависимостью.
Аналогично, если у вас есть A, который зависит от B и B, который зависит от C и C, который зависит от A, вы также будете иметь круговую зависимость. Или, если у вас есть C, который зависит от D, который зависит... ну, вы получите эту идею. В конечном итоге любой модуль, который зависит от любого другого модуля, должен гарантировать, что ни зависимый модуль, ни его зависимости не зависят от исходного модуля.
Итак, как вы исправляете свой код? Очевидным способом было бы удалить круговые зависимости, которые, безусловно, будут работать, но есть и другой вариант. Пусть говорят, что ваш A зависит от B, но только во время выполнения, а не во время загрузки. Другими словами, вместо:
// A.js
define(['B'], function(B) {
return B || function() {
// ...
};
});
у вас есть:
// A.js
define(['B'], function(B) {
return function() {
B();
};
});
В этом случае вы можете использовать единый аргумент "синхронный" форму запроса, чтобы избежать необходимости требовать "B" в верхней части вашего файла:
// A.js
define([], function() {
return function() {
var B = require('B');
B();
};
});
Потому что мы используем только B после того, как мы определили все наши модули. Требовать не нужно беспокоиться о A, идущем после B; он может определять его, когда захочет, потому что к тому времени, когда вы действительно хотите использовать B, он будет уже определен. Конечно, это предполагает, что у вас есть модуль, который на самом деле включает "B" наверху (если вы не требовали, даже не знал бы, что B существует).
Надеюсь, что это поможет.