0

我已经看到GWT.runAsync(...)从模块的onModuleLoad()方法内部以及其他方法中调用,因此从 GWT 应用程序内的任何地方拉下片段似乎是“合法的”。

但这让我开始思考:如果您可以从应用程序内的任何地方下载代码分割片段,那么当您运行此方法时,哪些 Java 类(在运行时已被编译为 JavaScript)实际上被拉下? 显然这是可配置的,但我找不到任何代码示例来说明如何配置从服务器端拉回的内容。即使在Codesplitting 的官方文档中,也只有客户端如何调用 GWT.runAsync的示例,而不是如何将其连接到服务器端片段。

JavaDocs中,此方法被重载,并且有两种变体:

  • runAsync(java.lang.Class<?> name, RunAsyncCallback callback); 和
  • runAsync(RunAsyncCallback callback)

前者允许您指定要从服务器拉回的特定类?如果是这种情况,您是否需要进行任何配置(配置类路径、搜索路径等),以便可以在运行时在服务器上找到该类并将其拉回?

最重要的是,后者的重载是如何工作的?!如果您没有指定要拉回的类,GWT 怎么知道要拉回什么?

例子

假设我的应用程序中有以下Something类,然后(以某种方式)放置在特定模块的片段之一中,然后编译成 JavaScript。此外,假设我正确配置了一些东西,因此存在于其中的片段Something被延迟并且不会与模块初始片段一起下载(因此它还没有“存在”在客户端浏览器中)。

public class Something {
    // ... Whatever
}

现在用户单击一个按钮小部件,我希望Something下载包含的片段,以便我们可以创建一个Something实例并对其进行操作。我如何使用GWT.runAsync来指定包含的片段Something

4

3 回答 3

2

正如 Thomas 在上面发布的那样,GWT 编译器会自动计算出它需要哪些片段。它通过分析您的代码并跟踪所有可能的执行路径来查看可以从哪里访问哪些代码来实现这一点。例如,假设您有类 A(主入口点类)、B、C、D、E、F 和 G,并且您有以下直接调用(即不使用 GWT.runAsync):

  • A呼叫B
  • B 呼叫 C
  • D 呼叫 E
  • F 呼叫 E

然后编译器将(可能)将您的代码拆分为以下块:

  • A,B,C(立即加载,因为立即需要 A
  • D(在 D 上调用 GWT.runAsync 时加载)
  • E(在 D、E 或 F 上调用 GWT.runAsync 时加载)
  • F(在 F 上调用 GWT.runAsync 时加载)
  • G(在 G 上调用 GWT.runAsync 时加载)

最近(在 GWT 2.5 中)在进行拆分以优化共享段的下载大小(上例中的 E)的方式方面发生了最近的变化。

因此,虽然没有设置本身允许您配置分割点的确切内容,但您可以通过构建代码的方式“选择”它们。无论如何,手动跟踪所有依赖项以确保所有需要的代码都可用,对您来说可能太难了。

如果您有兴趣了解编译器如何打包您的代码以及为什么打包,您可以打开编译报告。在这里,GWT 不仅会显示每个包的大小和内容,还会显示导致每个内容包含在段中的执行路径(A 调用 B,B 从上面调用 C)。这真的是一个非常了不起的工具。

因此,总而言之:稍微玩弄一下您的代码,以确保您了解编译器如何以及为什么做出打包决策,但除此之外,只需坐下来,让 GWT 编译器发挥其神奇的魔力!:)

更新:

回复:您添加的示例:美妙之处在于,GWT 编译器知道要加载哪个段,因此您无需告诉它任何内容。所有这一切都发生在幕后,您无需担心会发生什么(但了解正在发生的事情可能非常有用)。

于 2012-10-27T14:11:29.677 回答
1

它不可配置,由 GWT 编译器决定。在运行时没有什么特别的事情要做,编译器只是将生成的 JavaScript 拆分为几个.cache.文件而不是生成一个文件,然后GWT.runAsync用代码替换 以加载适当的.cache.文件。

于 2012-10-27T13:36:53.627 回答
1

假设在 runAsync 中创建了 MyUIScreen 类的实例。如果您的代码中的其他任何地方都没有引用该类,并且唯一的地方是在 runAsync 中,那么编译器会解决这个问题并将您的代码分解为 MyUIScreen 和其他所有内容。这大概就是将要发生的事情。因此,代码片段将在您从 runAsync 访问它的那一刻被下载

于 2012-10-27T14:10:40.100 回答