JavaScript:AMD(异步模块定义)中的'require'方法是同步的吗?

7

'require'在AMD(异步模块定义)中是同步的吗?如果是,那么这个规范如何变成异步的呢?如果我在代码中间有require()(并且它尚未加载),那么它会阻塞执行吗?讨论浏览器端。

2个回答

3
这里有两个不同的“同步”概念。第一个是“它会停止整个网页并等待文件吗?”答案是否定的。如果你有带有依赖项的脚本,RequireJS不会这样做。
如果你使用得当,它将使用一种 promise 系统。这意味着如果你发送回调并定义文件的要求,直到所有必需的文件都加载完毕,回调才会运行。
如果其中一个必需文件中有一个 require,则该回调将在其依赖项加载完成之前不会运行。最外层的回调(通常位于脚本底部)将在内部所有内容都运行完毕后运行。
这是基于 promise 系统工作的。值得了解 promise 系统的工作方式(某种程度上类似于观察者模式)。它们是基于事件传递或链式传递的,而不是以任何顺序多人监听。
var widget = new Widget(),  
    widgetLoaded = widget.load(url); // return a promise to let the program use the widget

widgetLoaded.then(function () { widget.move(35); })
            .then(function () { widget.setColour("Blue"); })
            .then(function () { widget.show(); });

这就像返回this以便您可以链接函数调用,不同之处在于直到widget.load()完成才实际发生调用。

widget将通过保留其承诺来控制此时机,如果小部件加载并且一切正常,则会履行其承诺,否则会违背其承诺。

在大多数Promise系统中,.then或任何称呼它的东西都需要两个函数(成功和失败 -- 在我的系统中,失败是始终可选的),或者它们采用具有 successfailure 的对象 -- $.ajax会这样做,然后让您预先确定加载数据时要执行什么操作,或者如果出现故障 -- Promise。

因此,您的页面仍然可以100%异步工作(无需中断UI),但它在所有模块按正确顺序触发时是100%同步的。

一个重要的事情你必须记住: 如果您的代码中存在这些依赖项,则不能在脚本底部等待运行的内联依赖项。 它们必须全部锁定在您的回调内,或者锁定在等待通过回调调用的功能内。

这仅仅是因为它在实际处理方面是异步的过程,不会阻止浏览器运行事件/JS、呈现页面等。


2

对于requireJS

在调用.require()方法时,你需要传递一个回调函数以及所需的模块,当资源加载成功时,该回调函数将被触发。因此,你只能在这个回调函数内访问已加载的AMD或CommonJS模块。

对于NodeJS:

是的,.require()方法是同步执行的。NodeJS使用的是CommonJS模块系统,而不是AMD。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接