使用 ngrx 时在分派完成后执行代码

Executing code after dispatch is completed while using ngrx

在我的示例 Angular 2 应用程序中,我使用 ngrx/store 和 ngrx/effects 进行状态管理。

下面是组件中添加新项目的函数之一。

addAuthor() {
    
    this.store.dispatch(addAuthorAction(this.fg.value));
    console.log('2')        
} 

在上面的代码中,this.store.dispatch(addAuthorAction(this.fg.value)); 负责对服务器进行 AJAX 调用并将新作者添加到 数据库,工作正常。

并且因为 this.store.dispatch(addAuthorAction(this.fg.value)); 是一个 async 动作,所以 console.log("2") 语句甚至在 AJAX 调用之前就被执行了 已完成。

我的问题是,需要修改什么才能在 store.dispatch 完成后执行 console.log。

快速回答:你不能。

正如你所说,dispatch 是异步的。

你应该做的是使用@ngrx/effects。它与使用 addAuthorAction 几乎相同,除了你不是调用函数,而是“捕获”调度的动作并在它们被 reducer 应用后立即做一些事情。

所以我通常做的是将我的动作分成 3 个,例如:

  • FETCH_USER

  • FETCH_USER_SUCCESS

  • FETCH_USER_ERROR

  • FETCH_USER 仅用于切换布尔值,因此我可以在获取用户时显示微调器

  • 我从一个效果中捕捉到这个动作并发出一个 http 请求来获取用户

  • 如果 http 响应正常并且我有我正在寻找的信息,我从效果 FETCH_USER_SUCCESS 发送响应作为负载,否则我发送 FETCH_USER_ERROR 然后我将布尔值切换为 false(例如,我们可以尝试再次获取他)。

所以在你的例子中,如果你想 console.log 在 FETCH_USER_SUCCESS 之后做一些事情,只需使用另一个效果来捕捉 FETCH_USER_SUCCESS 并在这里做你想做的事。

使用 ngrx,您可以收听这样的操作:

constructor(private actionsSubject$: ActionsSubject, private store: Store<AppState>) {}

ngOnInit() {
  this.actionsSubject$.pipe(
    takeUntil(this.unsubscribe$), // optional
    filter((action) => action.type === SimsActionTypes.SimEditedSuccess)
  ).subscribe(({payload}) => {
    console.log(payload)
  )
}

调度时 FIRST_ACTION 使用效果来发出 HTTP 请求。实际上,当您收到响应时,以响应作为有效负载触发 SECOND_ACTION。然后只需在控制器 .ts 文件中收听 SECOND_ACTION

测试

"@ngrx/core": "^1.2.0",
"@ngrx/effects": "^7.4.0",
"@ngrx/router-store": "^7.4.0",
"@ngrx/store": "^7.4.0",
"@ngrx/store-devtools": "^7.4.0",

这也有效:

import { ofType, Actions } from '@ngrx/effects';

// Constructor
constructor(
   private _actions$: Actions,
   private _store: Store<any>,
) { }

// YOUR METHOD    
this._store.dispatch(<ACTION>);
this._actions$.pipe(ofType(<ACTION_NAME>)).subscribe((data: any) => {
  console.log(data);  // returned state data        
})

由于分派是异步的(即发即弃),我们可以订阅返回的可观察对象,然后在获取可观察对象后执行下一条语句。

addAuthor() {
    this.store.dispatch(addAuthorAction(this.fg.value))
    .subscribe(() => {
        console.log('2')
    });           
}

或者,

myObservableObject$: Observable<any>;
this.myObservableObject$ = this.store.dispatch(addAuthorAction(this.fg.value));
this.myObservableObject$.subscribe((response) => {
    console.log('2')
});

以上是基于ngxs的状态管理框架。更多@https://www.ngxs.io/advanced/actions-life-cycle#asynchronous-actions