Angular中ClienteApiRestService两次subscribe并行导致CRUD更新异常原因问询
问题原因解析
这是RxJS异步流的典型执行逻辑问题,核心原因是subscribe本身属于非阻塞的异步方法:
- 你调用示例中的
putEnabled、getAllUsers这类HTTP请求方法时,返回的是RxJS的Observable对象,该对象仅在调用subscribe后才会真正发起网络请求。 subscribe触发请求后不会等待请求返回结果,会立刻向后执行后续代码。所以拆分写法下,putEnabled的subscribe触发更新请求后,代码不会等待更新请求完成,马上就会执行后续getAllUsers的subscribe触发查询请求,两个请求几乎同时发往后端,大概率查询请求先拿到结果,返回的自然是更新前的旧数据。- 嵌套写法的执行逻辑是:只有等
putEnabled的更新请求成功返回、触发第一个subscribe的成功回调后,才会执行getAllUsers的subscribe发起查询请求,两个请求是严格的先后执行顺序,因此能拿到更新后的最新数据。
写法优化建议
嵌套subscribe属于回调地狱的写法,后续维护成本高,更推荐用RxJS的切换操作符switchMap优化,优化后写法如下:
this.clienteApiRest.putEnabled(this.enableSelector, !this.enabled) .pipe( switchMap(() => this.clienteApiRest.getAllUsers(this.enabled)) ) .subscribe({ next: (resp: User[]) => { this.users = resp; console.log("datos: " + resp); resp.forEach(function (data) { // 原有遍历逻辑 }); }, error: err => console.log("Error: " + err) })
该写法逻辑层级更清晰,也方便后续扩展其他流处理操作。
内容的提问来源于stack exchange,提问作者Carlos Noé
相关产品推荐
相关产品推荐

