如何使用浏览器并行加载但仍使用RequireJS维护脚本的顺序

时间:2014-06-30 21:43:47

标签: javascript requirejs amd

我有这位讨厌RequireJS的朋友,我最近开始使用它&我喜欢它,但是通过他的论点,我开始觉得我可能会像他一样,放弃使用RequireJS

require(['one'],function(){
    require(['two'],function(){
        require(['three'],function(){

        });
    });
});

以上代码非常简单,three取决于two& two取决于one。这使得浏览器首先加载one&然后是two&然后three按顺序排列,requirejs如何处理它,如果存在大量这类依赖关系,这会使网站变得非常慢。

浏览器并行加载功能根本没用过。

我想知道require是否有任何方式异步加载所有这些文件,但确保在执行时保持顺序,以便可以使用浏览器并行性。

3 个答案:

答案 0 :(得分:2)

RequireJS是一个功能强大的工具,允许我们异步加载脚本(意味着我们开始加载每个脚本,不要等到实际加载),但仍然管理依赖项(如果一个文件依赖于另一个文件) ,我们想要确保预先加载依赖关系)。你使用RequireJS的方式不是它的用途。一旦加载了依赖模块,就会调用require中的回调函数(' one',' two',' three')。所以你只是按顺序加载所有模块,而不是异步加载(一个加载 - >回调函数被调用 - >两个被加载 - >回调函数被调用 - >三加载 - >调用回调函数) 。这是没有意义的。它的方式应该是:

在HTML文件中:

<script data-main='main.js' src='require.js'></script>
你的main.js文件中的

(你在脚本标签中写的一些文件为data-main):

require(['one'], function(one){
    one.function1();
});

在one.js中:

define(['two', 'three'], function(two, three) {
    return {
        function1 : function() {
            two.function2();
            three.function3();
            console.log('one');
        }
    }
});

in two.js:

define([], function() {
    return {
        function2 : function() {
            console.log('two');
        }
    }
});

in three.js:

define([], function() {
    return {
        function3 : function() {
            console.log('three');
        }
    }
});

在我的例子中,一个&#39;取决于&#39;两个&#39;和&#39;三&#39; (它需要来自&#39; two&#39;的function2()和来自&#39; three&#39;的功能3(),&#39; 2&#39;和&#39;三&#39;没有依赖。此示例代码假定所有文件都在一个文件夹中(包括require.js)。因此,我们会看到两个&#39;三个&#39;一个&#39;一个&#39;一个&#39;一个&#39;打印(按此顺序)。

答案 1 :(得分:0)

尽管RequireJS使用AMD模型加载脚本,但我们仍然可以自行管理模块评估顺序。如果您不想使用define(),可以使用名为 order!的特殊插件。它适用于RequireJS 1.0 API。它允许异步获取文件,但按特定顺序进行评估:http://requirejs.org/docs/1.0/docs/api.html#order

答案 2 :(得分:-1)

accepted solution适用于大多数用例,特别是因为它通常对use r.js to bundle everything有意义,这使并行加载成为一个有争议的问题。但是,此解决方案实际上并不允许并行加载所有模块,而是以3步序列加载,如下所示:[main.js] -> [one.js] -> [two.js, three.js](如果不使用r.js将文件打包为一个模块)或一个打包文件的单个加载(如果你使用r.js将所有文件打包到一个模块)。

如果你确实想要在一个并行的步骤中加载文件,例如:[one.js, two.js, three.js],你有两个选择:


:一种。使用RequireJS 1.0 +订单插件

gthacoder's other answer中涵盖了这一点。


<强> B中。包装脚本以便Require可以加载它们,然后在单独的阶段执行它们

这引入了一些复杂性,但非常可靠。关键是要并行加载的每个模块都应该在其中包含一个与用于加载文件的名称不匹配的命名模块。这将阻止模块执行,直到您明确告诉它:

<强> one.js

define('one-inner', ['two-inner'], function () {
  ...
});

<强> two.js

define('two-inner', ['three-inner'], function () {
  ...
});

<强> three.js所

define('three-inner', function () {
  ...
});

您的网页或main.js文件

// 1. Require loads one.js, two.js, and three.js in parallel,
// but does not execute the modules, because nothing has called
// them by the correct name yet.
require(['one', 'two', 'three']), function () {

       // 2. Kickstart execution of the modules
       require(['one-inner'], function () {
             ....
       }
});