TransferState:谁保证数据已经存入状态?
TransferState: Who guarantees that data is already stored in state?
我正在使用 TransferState 进行 SSR 并且
想知道当我们这样做时谁能保证
http.get(...).subscribe(data => {
transferState.set(DATA_KEY, data)
})
数据会存储在transferState?
因为 http.get 是异步操作 并且可以在没有此数据的情况下生成内容并提供给客户端。
Angular Zone 保证所有异步操作(zone.js 跟踪的调用)在渲染之前完成。
一起来看看
server.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 function returns 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);
});
它只会在从 renderModuleFactory
函数返回的 promise(3) 被解析后发生。
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));
}
上面可以看到我们其实运行Angular申请这里是通过platform.bootstrapModuleFactory(moduleFactory)
(4)
里面_render function(5) application waits for bootstrapping to be finished
return moduleRefPromise.then((moduleRef) => {
然后我们可以看到 the key 的答案:
return applicationRef.isStable.pipe((first((isStable: boolean) => isStable)))
.toPromise()
.then(() => {
可以看到angular universal 看ApplicationRef.isStable observable to know when to finish rendering. In simple words isStable on ApplicationRef is triggered when Zone has no microtasks scheduled (7):
if (!zone.hasPendingMicrotasks) {
try {
zone.runOutsideAngular(() => zone.onStable.emit(null));
我正在使用 TransferState 进行 SSR 并且 想知道当我们这样做时谁能保证
http.get(...).subscribe(data => {
transferState.set(DATA_KEY, data)
})
数据会存储在transferState? 因为 http.get 是异步操作 并且可以在没有此数据的情况下生成内容并提供给客户端。
Angular Zone 保证所有异步操作(zone.js 跟踪的调用)在渲染之前完成。
一起来看看
server.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 function returns 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);
});
它只会在从 renderModuleFactory
函数返回的 promise(3) 被解析后发生。
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));
}
上面可以看到我们其实运行Angular申请这里是通过platform.bootstrapModuleFactory(moduleFactory)
(4)
里面_render function(5) application waits for bootstrapping to be finished
return moduleRefPromise.then((moduleRef) => {
然后我们可以看到 the key 的答案:
return applicationRef.isStable.pipe((first((isStable: boolean) => isStable)))
.toPromise()
.then(() => {
可以看到angular universal 看ApplicationRef.isStable observable to know when to finish rendering. In simple words isStable on ApplicationRef is triggered when Zone has no microtasks scheduled (7):
if (!zone.hasPendingMicrotasks) {
try {
zone.runOutsideAngular(() => zone.onStable.emit(null));