IsStable:首先 false,然後 true
@NgModule()
export class CartPersistenceModule {
static forRoot(): ModuleWithProviders<CartPersistenceModule> {
return {
ngModule: CartPersistenceModule,
providers: [
{
provide: APP_INITIALIZER,
useFactory: cartStatePersistenceFactory,
deps: [MultiCartStatePersistenceService, ConfigInitializerService],
multi: true,
},
提供的函式在應用程式啟動時注入並在應用程式初始化期間執行。 如果這些函式中的任何一個返回 Promise 或 Observable,則在 Promise 解決或 Observable 完成之前,初始化不會完成。
例如,我們可以建立一個載入語言資料或外部配置的工廠函式,並將該函式提供給 APP_INITIALIZER 令牌。 該函式在應用程式引導過程中執行,所需資料在啟動時可用。
應用程式初始化時,呼叫 cartStatePersistenceFactory
:
Angular 框架呼叫所有的 app initializer:
這個 init 需要返回一個 promise 物件:
toPromise 物件內會呼叫 subscriber 的 next 方法:
呼叫 cartStatePersistenceService.initSync()
:
cart 資訊儲存在 local storage 裡:
從 local storage 裡取出的資料:
生成 key:
SSR 模式下沒有瀏覽器 storage:
取出瀏覽器 local storage 裡儲存的當前 active cart id:2007
也就是下圖高亮的 cart id:
不同的 base site,其對應的 cart id 不一致。
得到 cart id 後,呼叫 onRead
方法:
首先 clear Cart 狀態:
進入 scheduleMessage,即利用 store 進行 Action dispatch,很有可能是一個非同步過程。
然而沒有進入非同步 schedule 的分支:
直接呼叫 scheduler 的 flush 方法:
呼叫 Observer 的 next 方法:
重新計算 state,並且把結果儲存:
computedStates = recomputeStates(computedStates, minInvalidatedStateIndex, reducer, committedState, actionsById, stagedActionIds, skippedActionIds, errorHandler, isPaused);
monitorState = monitorReducer(monitorState, liftedAction);
前一個狀態:
呼叫 reducer 計算下一個狀態:
這就是 Spartacus 自己實現的 reducer 了:
export function reducer(
state = initialState,
action: CmsActions.LoadCmsPageDataSuccess
): EntityState<Page> {
switch (action.type) {
case CmsActions.LOAD_CMS_PAGE_DATA_SUCCESS: {
const page: Page = action.payload;
return { ...state, entities: { ...state.entities, [page.pageId]: page } };
}
}
return state;
}
會依次執行很多對應的 reducer: