请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于连续发送多条请求的问题

老师你好,有个问题卡了我很久,想问一下你。
考虑一种情况,从Angular这边连续发送多条请求到后端。
数据如下:

{ id: 1, name: 'test01'}	// 第一条请求的数据 req1
{ id: 2, name: 'test01'}	// 第二条请求的数据 req2
{ id: 1, name: 'test02'}	// 第三条请求的数据 req3

在后端进行保存的时候,name有唯一性约束,并且每条数据都有乐观锁(optimistic lock)

  1. 考虑第一和第二条请求(req1, req2)
    每条数据在保存前都会判断name的唯一性。此时数据库里没有name为‘test01’的数据,所以req1 name check过了,然后进行保存。
    此时第二条请求req2到了,而req1还处在保存的过程中没有结束,所以此时数据库里还是没有name为’test01’的数据,所以req2的name check也通过了,也会进行保存。
    这样导致的问题就是:req1结束时保存成功,而req2最终会失败,因为虽然name check通过了,但最终进行保存的时候name还是重复了。

2)考虑第一和第三条请求(req1与req3)
数据在保存前会判断乐观锁。req1与req3为同一条数据的两条请求。如果在请求发送之前,id为1的数据乐观锁为1。在req1的数据进行保存之前,会先从数据库中拿到其乐观锁,然后set到当前数据的乐观锁。
然后保存req1的数据时,判断当前的乐观锁为1,为最新的数据,可以进行保存。
此时,同意地,在req1还在保存的过程中,req2到了。此时数据库里当前数据的乐观锁还是1。所以req2最终也会以乐观锁为1的状态进行保存。
与第一个问题相似,req1会成功,req2会失败。

针对这两种情况,如果希望angular这边在发送请求时做改进,有什么好的办法呢。这看起来不像是纯Angular的问题,但是我需要在前端angular这边做改动,考虑了很久也没有什么好的办法。
求助一下老师,谢谢了!

正在回答 回答被采纳积分+3

1回答

接灰的电子产品 2020-05-14 22:17:03

这个事情完全看你的业务需求是什么,而且看你的描述,其实和后端无关。那么就来看前端,首先连续发送请求是有意为之,还是写的方法不对导致的?如果不是有意为之,我建议找到问题源头去阻止。

有意为之,rxjs 有非常强大的操作符去处理, 比如 filter 可以用于过滤,比如 distinctUntilChanged 也可以把相同参数的过滤掉,再有利用 concat 或 concatMap 可以强制请求排序,一个返回了才执行另一个。具体应该使用什么看你的业务要求了

1 回复 有任何疑惑可以回复我~
  • 提问者 流叠 #1
    需求就是这样,需要连续发送请求。就是在对数据做增删改查,所以有时候如果点击够快的话就会对同一条数据发送多条请求,但实际上最后一条请求的数据才是我需要的最终的数据。或者发送两条相同name的请求过去,会造成预料之外的错误。我有想过对发出的请求做一些处理,但是理论上来说同一条数据的最后一条请求才是我需要的,如果是这种情况,我要怎么样去对请求做处理,因为收到第一条请求的时候,还未知后面的请求是怎样的。而对不同数据之间的请求应该互不干扰。
    回复 有任何疑惑可以回复我~ 2020-05-14 22:31:00
  • 提问者 流叠 #2
    也有考虑过使用concatmap去强制请求一条一条发送,但是每条请求的返回结果都会刷新界面,就像一个checkbox如果我连续点击两次就会发送两次请求,如果请求时间稍微满了些,第一次的请求,checkbox由true变false,界面刷新,第二次的请求 checkbox由false变true,界面又刷新一次。
    如果当前checkbox为true,连续点击两次之后仍是true,但是两次请求会导致 checkbox从true变false再变为true,这种行为看起来会很奇怪
    回复 有任何疑惑可以回复我~ 2020-05-14 22:33:39
  • 接灰的电子产品 回复 提问者 流叠 #3
    你说的这种问题本质上是一个要加入防抖处理(debounceTime 和 debounce 操作符)以及UI 上的点击后有 loading 的一个方式。因为所谓的快速点击想获得最后一个,其实就和输入关键字出现提示是一样的,我们不想每个快速输入或点击都生效,就应该有对输入或点击的防抖处理。
    另外所谓界面状态的刷新,其实一共就两种方式,要么点击时立刻反应,如果请求失败再变回来;要么等待服务端返回。无论那种方式,其实都需要 UI 的配合和设计。这个没什么好办法的。
    回复 有任何疑惑可以回复我~ 2020-05-15 00:20:19
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信