AMD(异步模块定义)中的“要求”是同步的吗?如果是这样,是什么让这个规范异步?如果我在我的代码中间有 require() (它还没有被加载),它会停止执行吗?谈论浏览器端。
2 回答
这里有两个不同的synchronous
概念。第一个是“它会停止我的整个网页,然后坐下来等待文件。”。
答案是不。如果您有一个具有依赖关系的脚本,RequireJS 不会这样做。
如果你使用得当,它会使用一个承诺系统。这意味着如果您发送回调并定义对该文件的要求,则在加载所有必需的文件之前不会运行回调。
如果在这些必需文件之一中存在需求,则在加载ITS依赖项之前不会运行该回调。
最外层的回调(通常位于脚本底部的回调)不会运行,直到里面的所有内容都有。
这适用于承诺系统。值得了解 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
或者不管他们怎么称呼它,要么接受两个函数(保留和破坏——在我的系统中,破坏总是可选的),或者他们接受一个对象success
和failure
——$.ajax
这样做,然后让你预先确定你的想要在加载数据时处理数据,或者如果它失败 - 承诺。
因此,您的页面仍然 100% 异步工作(不会中断 UI),但它是 100% 同步的,因为所有模块都将以正确的顺序触发。
您必须记住的一件事:如果您的代码中有这些依赖项,那么您的脚本底部就不能有任何依赖项,等待运行,内联。它们必须全部锁定在您的回调中,或者锁定在等待您的回调调用的函数中。
这仅仅是因为它是一个异步进程,就实际处理而言,不会阻塞浏览器运行事件/JS、渲染页面等。
对于requireJS:
您必须将回调方法与所需模块一起传递给.require()
,当资源成功加载时将触发该方法。所以,当然你应该/只能在回调中访问加载的 AMD 或 CommonJS 模块。
对于 NodeJS:
是的,.require()
确实同步工作。NodeJS 使用 CommonJS 模块系统,而不是 AMD。