0

我正在尝试使用 Almond.js 和 Require.js 优化器来制作一个可以在没有 Require.js 的情况下使用的独立文件。我已经能够成功编译该文件,并且所有代码都运行了,但是有一个问题:代码以错误的顺序执行。

假设我的主文件(include=传递给优化器的选项中的那个)具有以下内容:

console.log('outside');
require(['someFile'], function(someModule) {
    console.log('inside');
    window.foo = someModule.rightValue;
});

然后在我的HTML中我有:

<script src="myCompiledFile.js"></script>
<script>
    console.log('out in the HTML');
</script>

由于我使用的是 almond.js 和一个编译文件(因此没有文件加载正在进行),我希望得到输出:

outside
inside
out in the HTML

然而,事实证明仍然存在一些异步性,因为我实际看到的是:

outside
out in the HTML
inside

如果我尝试window.foo从 HTML 检查它不存在。

所以,我的问题是,我怎样才能让代码更像一个普通/同步的 JS 文件,在将内容传递到下一个script块之前首先运行它的所有代码?我不能准确地告诉我的用户“将所有代码包装在 window.setTimeout 中”。

4

1 回答 1

2

默认情况下,Almond 复制了 RequireJSrequire调用的时间语义。由于require在 RequireJS 中是异步的,所以在 Almond 中也是异步的。这可以在源代码中很容易地观察到:Almond 使用 asetTimeout来安排模块的执行,即使它可以立即执行它。这是有道理的,因为在一般情况下,开发人员并不期望他们编写的异步工作代码会因为使用 Almond 而突然变得同步。在每个项目中都没有关系,但在 UI(例如)应按特定顺序刷新的项目中,更改时序语义可能会破坏代码。

两种选择:

  • 正如setTimeout各州之前的评论,使用require('id')全球范围内与杏仁一起使用。这是因为一旦你的包被加载,所有的东西都保证已经加载(因为 Almond 不会动态加载)。

  • 还有一种方法可以require使用额外的参数进行调用。如果第四个参数为真,则调用将是同步的:

    require(['someFile'], function(someModule) {
        console.log('inside');
        window.foo = someModule.rightValue;
    }, undefined, true);
    

这可以通过阅读杏仁的代码来确定。我找不到任何文档forceSync(这是有问题的参数的名称),但一些错误报告提到了它,我没有看到任何评论表明它是私有功能。

于 2014-03-05T11:12:45.713 回答