我相信下面的所有四种方法都可行,但我不清楚为什么有人会使用前三种方法,因为它的代码更多。但是,第一个(也是最详细的)是RequireJS docs中给出的那个。
define "circular1", ["example1"], -> "circular1"
define "circular2", ["example2"], -> "circular2"
define "circular3", ["example3"], -> "circular3"
define "circular4", ["example4"], -> "circular4"
#1
define "example1", ["require", "circular1"], (require, circular) ->
alert "example1 Before: " + circular
circular = require "circular1"
alert "example1 After: " + circular
#2
define "example2", ["require"], (require) ->
alert "example2 Before: " + circular
circular = require "circular2"
alert "example2 After: " + circular
#3
define "example3", ["circular3"], (circular) ->
alert "example3 Before: " + circular
circular = require "circular3"
alert "example3 After: " + circular
#4
define "example4", [], ->
alert "example4 Before: " + circular
circular = require "circular4"
alert "example4 After: " + circular
require ["example1"], ->
require ["example2"], ->
require ["example3"], ->
require ["example4"], ->
circularDependency
之前未定义require
,那么在定义(#1&#3)中包含它的烦恼是什么? require
在加载第一个脚本时始终全局可用,为什么要将其传入?这只是代码清晰度的问题,即。是不是只提供了代码顶部所有依赖关系的简洁快照(因为你可能实际上不会在明天之前找到显式的require
?或者它对RequireJS的做法有一些实际影响优化取决于它是否包含在define
?我不想使用任何这些变体,如果它对我的软件产生负面影响只是因为它“有效”。
答案 0 :(得分:1)
当RequireJS将每个模块作为单独的文件加载而不是将它们全部捆绑起来时,它会产生影响。在依赖项列表中指定模块会告诉RequireJS在调用模块的函数之前需要加载该模块。由于require
是同步的,并且不会尝试同步加载脚本,如果脚本尚未加载,则无法返回模块。由于require
应该解析相对于需求模块的相对模块ID,因此您需要使用它传递给您的require
。所以:
第一种方法是正确的。它告诉RequireJS加载模块(如果尚未加载)。如果circular
最初为undefined
,则可以很快将其填充到其他模块中。
第二种方式不正确。如果尚未加载circular2
,则对require
的调用将无效。它将正确解析模块ID,因为它使用的是require
。
在这种情况下,第三种方法是正确的 ,但是如果你传递了一个相对模块ID,如./circular3
,那么将无效。它也告诉RequireJS加载模块(如果尚未加载),这样你就不会遇到#2中的问题。唯一的区别是它使用全局require
,它缺少传递给工厂函数的require
的上下文,所以如果你传递一个相对的模块ID,如./circular3
,它不会我不知道相对于它来解决它。
这种方式结合了#2和#3的不正确性。首先,它无法正确解析相关模块ID。其次,即使它可以正确解析相对ID,如果它们尚未加载,它仍然不会加载模块。
如果你可以保证在circularN
模块需要它之前总是定义exampleN
模块,那么是的,它会起作用,但使用方法#1和#3确保它能工作即使情况并非如此。