javascript - 水龙头不等待角度后端服务调用的响应
问题描述
在服务中使用 tap 运算符时如何订阅响应。
有谁知道如何解决这个问题?
edit(status) {
dataObj.val = status;
// call post service with status..
this.service
.update(dataObj)
.pipe(takeUntil(this._ngUnsubscribe$))
.subscribe(() => {
//i would like to wait until response come from backend and then navigate to the page so i get data over there.
if (res.status === 'Success') {
this.router
.navigate(['../../success'], {
relativeTo: this.route,
})
.then(() => {});
} else {
this.location.back();
}
});
}
//akita store service
update(
obj: any,
): Observable < any > {
return this.service.update(obj).pipe(
delay(800),
map((data: RestfulResponse < any > ) => data.data),
tap((data: anny) => {
this.store.update((state) => {
state.updateValue = data; // value is not updating and it is navigating to route
});
}),
);
}
//post service
update(obj){
//post call
}
有什么方法可以在服务端使用点击并在组件端订阅?
我知道我可以使用 finalize ,但它对编写内部条件没有帮助。
解决方案
按照tap
设计,操作员可以处理在可观察管道的上下文中不会发生的副作用。这意味着您的管道永远不会等待tap
自身的结果。我不建议以这种方式使用它。大多数情况下,我只tap
用于调试。
如果您正在等待特定的状态更改,您应该创建一个单独的可观察对象,从您的商店中选择,以观察预期更改的状态。
如果您想在发生某些事情时触发其他操作,我建议使用 ngrx Effects来实现这一点。
看看这篇文章,我在其中谈到了如何实现类似的用例: https ://stackoverflow.com/a/64491398/166850
您还应该努力设置应用您的状态更改的减速器,而不是直接更新商店。
将以下每一项视为一个单独的关注点,您可以独立于其他关注点来实现:
- 当用户进行编辑时,触发编辑动作。
- reducer 应该根据编辑操作更新状态(例如,显示正在保存)
- 当编辑动作被触发时,触发一个效果。应用程序应进行 HTTP 调用以保存更改,然后触发保存完成操作。
- 保存完成后,应触发路由器导航。
这会将您的代码分成多个单元,这些单元易于独立测试和验证。
如果 #1 产生一个被你的 reducer (#2) 消耗的动作,你还可以为 #3 创建一个 ngrx 效果,它监听相同的动作,使用 处理 HTTP 调用switchMap
,然后触发另一个动作来表示它已经完成。
编辑
这是一个简单的例子。第一次(从 AppComponent)触发名为 APP_LOADED 的动作时,此效果会进行 HTTP 调用以从服务器获取数据,然后使用响应数据作为动作负载触发动作。
实际的 HTTP 调用被委托给另一个服务,HttpMyConfigDataService
,它只是调用HttpClient
并返回一个Observable
.
@Injectable({
providedIn: 'root'
})
export class LoadMyConfigEffect {
constructor(
private httpMyConfigDataService: HttpMyConfigDataService,
private action$: Actions
) {
}
loadMyConfigData$ = createEffect(() => {
return this.action$.pipe(
filter((action) => action.type === 'APP_LOADED'),
take(1),
switchMap(() => this.httpMyConfigDataService.get().pipe(
map(data => {
return {type: 'MY_CONFIG_DATA_LOADED', payload: data};
}),
catchError(err => {
console.error('Error loading config data.', err);
return of({type: 'CONFIG_LOAD_ERROR', payload: err.message, isError: true);
})
))
);
});
}
推荐阅读
- c# - 为什么 NuGet 包 NLog 不适用于 .NET Core?
- networking - 连接到自己的网络守护进程是什么意思?
- angular-material - 角度材料选择列表 - 可以通过键盘选择/取消选择禁用的选项
- c# - 如何创建任务栏上方且没有滚动条的全屏控制台?
- visual-studio-code - Visual Studio Code - 启动调试操作
- excel - 如何在 VBA 中使用单元格格式设置 VLookUp?
- c# - cURL 到带有参数的 C# HttpWebRequest
- python - 在熊猫中如何删除数字序列中的列?
- php - 选择第二个值
- php - 从由字符和具有相同字符的整数组成的字符串中添加整数