代码之家  ›  专栏  ›  技术社区  ›  Stepan Suvorov bolelamx

TransferState:谁保证数据已经存储在状态中?

  •  8
  • Stepan Suvorov bolelamx  · 技术社区  · 6 年前

    我正在做 带传输状态的SSR 和 想知道我们什么时候能保证

    http.get(...).subscribe(data => {
      transferState.set(DATA_KEY, data)
    })
    

    数据将存储在 转移状态 ? 因为 http.get是异步操作 内容可以在没有这些数据的情况下生成并提供给客户机。

    1 回复  |  直到 6 年前
        1
  •  4
  •   yurzui    6 年前

    AngularZone保证在渲染之前完成所有异步操作(zone.js跟踪的调用)。

    让我们看看

    Serv.ts

    app.get('*', (req, res) => {
      res.render('index', { req });
    });   
                          ||
                          \/
    app.engine('html', ngExpressEngine({
      bootstrap: AppServerModuleNgFactory,
      providers: [
        provideModuleMap(LAZY_MODULE_MAP)
      ]
    }));
    

    我们可以看到所有常规路由都使用通用引擎来呈现HTML。

    res.render 方法(1)定义 default callback . 这个 ngExpressEngine 函数返回 another function with that callback 作为参数(2)传递。一旦该回调被触发,Express就会将结果发送给用户。

    done = done || function (err, str) {
      if (err) return req.next(err);
      self.send(str);
    };
    

    现在让我们看看什么时候 callback will be triggered . 如前所述,我们需要查看ngexpressengine函数。

     getFactory(moduleOrFactory, compiler)
       .then(factory => {
           return renderModuleFactory(factory, {
              extraProviders
           });
        })
        .then((html: string) => {
          callback(null, html);
        }, (err) => {
          callback(err);
    }); 
    

    只有当承诺(3)从 renderModuleFactory 功能,已解决。

    rendermodulefactory(渲染模块) 函数可以在以下位置找到 @angular/platform-server

    export function renderModuleFactory<T>(
        moduleFactory: NgModuleFactory<T>,
        options: {document?: string, url?: string, extraProviders?: StaticProvider[]}):
        Promise<string> {
      const platform = _getPlatform(platformServer, options);
      return _render(platform, platform.bootstrapModuleFactory(moduleFactory));
    }
    

    你可以看到上面我们实际运行角度应用程序 platform.bootstrapModuleFactory(moduleFactory) (四)

    里面 _render 函数(5)应用程序等待 bootstrapping to be finished

    return moduleRefPromise.then((moduleRef) => {
    

    然后我们就可以看到 the key 答案是:

    return applicationRef.isStable.pipe((first((isStable: boolean) => isStable)))
            .toPromise()
            .then(() => {
    

    你可以看到这个角度宇宙 ApplicationRef.isStable 可以观察到,知道什么时候完成渲染。简单来说,当 Zone has no microtasks scheduled (7):

    if (!zone.hasPendingMicrotasks) {
      try {
        zone.runOutsideAngular(() => zone.onStable.emit(null));
    

    enter image description here