Angular Universal构建因API请求而挂在预渲染页面上

时间:2018-09-22 16:56:32

标签: angular typescript angular-cli angular-universal

我正在开发一个基于angular universal starterpokeapi的小型Web应用程序。由于我要显示的许多数据实际上并未更改,因此我想使用预渲染的页面来减少对API的请求数量并提高性能。在我的示例中,我将口袋妖怪的列表放在了我的应用的首页上,该清单是从API检索的。

export class HomeComponent implements OnInit {

    pokemon$: ReplaySubject<ResourceList> = new ReplaySubject<ResourceList>();

    constructor(private pokedexService: PokedexService, private state: TransferState) { }

    ngOnInit() {
        if (this.state.hasKey(STATE_KEY_POKEMON)) {
            this.pokemon$.next(this.state.get(STATE_KEY_POKEMON, {} as ResourceList));
        }
        else {
            this.pokedexService.getResourceByCategory(ResourceCategory.POKEMON)
                .subscribe((resourceList: ResourceList) => {
                    this.pokemon$.next(resourceList);
                    this.state.set(STATE_KEY_POKEMON, resourceList.results);
                });
        }
    }
}

当我让客户端呈现页面时,这可以正常工作。但是,当我尝试预渲染应用程序时,构建过程会挂起。由于我正在运行该API的本地实例,因此可以看到发出了一个请求,并返回了200状态。构建日志如下所示:

npm run build:prerender

> ng-universal-demo@0.0.0 build:prerender C:\Users\thijs\Development\pokedex universal\angular-universal-pokedex
> npm run build:client-and-server-bundles && npm run compile:server && npm run generate:prerender


> ng-universal-demo@0.0.0 build:client-and-server-bundles C:\Users\thijs\Development\pokedex universal\angular-universal-pokedex
> ng build --prod && ng run ng-universal-demo:server:production


Date: 2018-09-22T16:47:41.687Z
Hash: c49708f1ccb7e73e327a
Time: 8181ms
chunk {0} runtime.6afe30102d8fe7337431.js (runtime) 1.05 kB [entry] [rendered]
chunk {1} styles.34c57ab7888ec1573f9c.css (styles) 0 bytes [initial] [rendered]
chunk {2} polyfills.c174e4dc122f769bd68b.js (polyfills) 64.3 kB [initial] [rendered]
chunk {3} main.19481e4ceb7a5808fe78.js (main) 312 kB [initial] [rendered]

Date: 2018-09-22T16:47:50.816Z
Hash: ee7e30e1f9c277bb5cbf
Time: 5739ms
chunk {main} main.js (main) 38.2 kB [entry] [rendered]

> ng-universal-demo@0.0.0 compile:server C:\Users\thijs\Development\pokedex universal\angular-universal-pokedex
> tsc -p server.tsconfig.json


> ng-universal-demo@0.0.0 generate:prerender C:\Users\thijs\Development\pokedex universal\angular-universal-pokedex
> cd dist && node prerender

完成预渲染构建的唯一方法是删除Web请求。我认为在后台仍然必须运行某些内容。我尝试将Observable切换为Promise,但这并没有改变任何内容。我想念什么?

You can find my project on GitHub

1 个答案:

答案 0 :(得分:2)

有点晚了,但是如果有人挣扎,这可能会有所帮助:

与上述有关等待宏任务完成的部分类似, 不利的一面是平台不会等待微任务执行 在完成渲染之前完成。在Angular Universal中,我们有 修补了Angular HTTP客户端以将其转换为宏任务,以确保 对于给定的渲染,任何所需的HTTP请求都将完成。然而, 这种类型的补丁可能不适用于所有微任务,因此 建议您最好地判断如何进行。您 可以查看代码参考,了解Universal如何包装要翻转的任务 将其转换为宏任务,或者您可以选择更改服务器 给定任务的行为。

基本上,如果您的http请求花费的时间太长,则预渲染将挂起并且无法完成。 另外,当我遇到此问题时,终端中没有错误输出,这使调试变得非常困难。