RequireJS的require调用什么时候是异步的?什么时候是同步的?

7

我在我的一个项目中使用RequireJS来加载模块。 我在网上看到了不同的用于调用require(而非define)来引入模块的方法。

假设我有一个名为“JQuery”的模块,我想要引入它。 根据我所看到的例子,有两种方式可行:

  1. This:

    require(["JQuery"], function($){
       $.doSomething();
    })
    
  2. And this:

    var $ = require("JQuery");
    $.doSomething();
    

我的问题是,如果负载是异步的,就像RequireJS文档所说的那样,第二个约定如何工作?我怎么能确定$被定义了,并且第一行完成后才执行第二行?

3个回答

13

RequireJS始终以异步方式加载模块,但它允许一种看起来同步的require形式。实际上,您的第二个代码片段缺少一些非常重要的代码。(此外,jQuery的模块名称硬编码为jquery。您可以编写一个配置文件,使其称为jQuery,但这没有意义。)这种require调用形式旨在在模块内使用:

define(function (require) {
    var $ = require("jquery");
    $.doSomething();
});

RequireJS在执行上述代码之前会将其转换为以下代码:

define(['jquery'], function (require) {
    var $ = require("jquery");
    $.doSomething();
});

注意将依赖项作为 define 的第一个参数添加。当 RequireJS 执行代码时,它会找到依赖项,加载 jquery,然后调用匿名函数。在遇到 require("jquery") 时,模块已经加载完毕。最终看起来 require 调用是同步的,但它所需的模块加载仍然是异步的。

你能在 define 调用之外使用这个同步形式的 require 吗?只有在你不介意出现错误的情况下才可以。 如果传给它的模块尚未加载,此 require 调用将失败。你将会得到臭名昭著的错误:

Module name ... has not been loaded yet for context: ...

像我上面展示的那样在define中使用是安全的。或者你可以这样做:

require(['jquery'], function (require) {
    var $ = require("jquery");
    $.doSomething();
});

可以工作,但是手动重复依赖有什么意义呢。(以防你想知道,RequireJS 不会像我在这里的示例中展示的转换一个带有回调函数的require调用,就像它转换define调用一样。)


谢谢。现在一切都清楚了,我认为第二种方式的代码看起来更漂亮、更整洁。 :) - Er85

0

我不了解requirejs。但我认为可以以同步和异步的方式加载模块。

function require(name,cb){
    if(cb !== undefined){
        requireAsync(name,cb);
    }else{
        requireSync(name);
    }
}

0
根据require.js文档,它是一个包装器。因此,它正在重建代码以异步工作。它被称为CommonJs包装器。您可以在这里找到更多信息。

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