我相信下面的所有四种方法都会起作用,但我不清楚为什么有人会仅仅因为代码更多而使用前三种方法。然而,第一个(也是最详细的)是 RequireJS 文档中给出的。
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"], ->
- 如果在执行显式
require
之前,circularDependency
是未定义的,那么费心将其包含在定义中有何意义(#1 和 #3)? - 如果
require
在加载第一个脚本时始终全局可用,为什么还要传入它呢?这只是代码清晰度的问题吗?是否只是为了在代码顶部提供所有依赖项的简洁快照(因为您可能直到很久以后才真正了解显式require
?或者它对RequireJS 如何根据是否包含在define
中进行优化?
如果这些变体仅仅因为它“有效”而对我的软件产生负面影响,我不想使用任何变体。
最佳答案
当 RequireJS 将每个模块作为单独的文件加载而不是将它们全部捆绑在一起时,就会产生影响。在依赖项列表中指定模块会告诉 RequireJS 在调用该模块的函数之前需要加载该模块。由于 require
是同步的,它不会尝试同步加载脚本,如果脚本尚未加载,它就无法返回模块。由于 require
应该解析相对于请求模块的相对模块 ID,因此您需要使用它传递给您的 require
。所以:
第一种方法是正确的。如果模块尚未加载,它会告诉 RequireJS 加载该模块。如果
circular
最初是未定义
,那么它很快就可以用其他模块填充它。第二种方式不正确。如果 circular2 尚未加载,则对 require 的调用将不起作用。它将正确解析模块 ID,因为它使用了给定的
require
。在这种情况下,第三种方法是正确的,但如果您向其传递一个相对模块 ID,如
./circular3
,它将不起作用。如果模块尚未加载,它也会告诉 RequireJS 加载该模块,因此您不会遇到 #2 中的问题。唯一的区别是它使用全局require
,它缺少传递给工厂函数的require
的上下文,因此如果您向它传递一个相对模块 ID,如./circular3
,它不知道相对于什么来解析它。这种方式结合了 #2 和 #3 的不正确之处。首先,它无法正确解析相关模块ID。其次,即使它可以正确解析相对 ID,如果模块尚未加载,它仍然不会加载模块。
如果您可以保证 circularN
模块始终在 exampleN
模块需要它之前定义,那么是的,它可以工作,但使用方法 #1 和 # 3 确保即使情况并非如此,它也能正常工作。
关于javascript - 处理循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17182039/