写点什么

谣言粉碎机 - 极短时间内发送两个 Odata request,前一个会自动被 cancel 掉?

用户头像
Jerry Wang
关注
发布于: 2021 年 05 月 23 日
谣言粉碎机 - 极短时间内发送两个Odata request,前一个会自动被cancel掉?

背景

有时我们能在 Chrome 开发者工具的 Network tab 里观察到 SAP UI5 应用会发出某些状态为"取消"的 OData 请求。如下图第五个请求。


之前有一种似是而非的说法:极短时间内发送两个 OData 请求,则第一个会自动被 cancel 掉。



这个说法从字面上看,有两点值得推敲:


1. cancel 掉,被谁 cancel 掉?UI5 框架还是 Chrome?


2. “极短”,多短算极短?


我用代码在 for 循环里一共发 10 个 OData 请求:



无论是同步还是异步,都没有任何的请求被 cancel。


10 个同步请求:



10 个异步请求:



就算发 100 个 request 都不会有一个 request 被 cancel:



验证结果,之前的说法“极短时间内发送两个 OData request,前一个会自动被 cancel 掉”是错误的。


那再回到本文第一张图观察到的 cancel 的场景, 原因究竟是什么?


观察产生了被取消的 OData 请求的应用代码,观察到第 523 行有这个 refresh 操作:



在这个方法的第 601 行,bChangeDetected 变量为 true 导致 abortPendingRequest 的调用。



abortPendingRequest 的注释已经很清楚地说明问题了。



什么情况下会导致 AbortPendingRequest? 直接使用 Chrome 开发者工具的全文搜索得到答案:OData model 的三个 API: filter, sort, refresh



下面是我的同事 Li Ben 的进一步补充。

关于这个现象发生的原因和条件的问题

1. 在哪里可以看到这个 cancel 现象?


在我们的 live search 功能上,如果输入较快或者正常速度输入,会看到前面很多输入请求都会被 cancel 掉:



如果输入较慢则不会:



真的是快慢的原因吗?


仔细观察 network 发现,真正的原因是当上一次的 network 还处于 pending 状态的时候,继续输入发起的请求就会 cancel 掉上一次的请求:



继续深究, 这是在哪里做到的?


在 SAP UI5 的 OData 框架里面有这样的实现:


在 ODataModel.js 中维护了一个 http request 的 pending list,将已经发送但是还没有收到响应的 request 对象都缓存在这个列表中:



每次发起 OData 请求的时候都会调用 ODataModel 的_request()方法,这个方法会把当前的 request 加到 pending list 中,并且通过一个 wrap method 包装回调函数,确保在响应返回的时候首先把缓存的 request 对象从 pending list 中拿掉:



每次在 OData Model 上发起 filter, sort, refresh 操作的时候,都会检查是否存在 pending 的 request 对象,如果存在未完成的请求,abort 掉它:



回答上面的问题,在什么情况下会发生这种现象?


1. 同一个 ODataModel 的 instance 上发出的连续请求,因为 pending list 是缓存在 this 级别上面的。


2. 前一个 Http 请求的 network 还处于 pending status 的时候。


3. 就读 ODataModel 的代码和观察到的现象,在 ODataModel 上发起 filter, sort 或者 refresh 的时候。


为什么在 OData 的 request 对象上发起 abort 调用就可以取消底层的 network call?


简单的说,UI5 里面的 OData Request 对象是底层的 Ajax Request 对象 XmlHttpRequest 的一个代理,在 ODataModel 的_submit 方法中:



具体实现是 UI5 中利用了一个第三方的库 datajs,datajs 最终会调用浏览器的底层 http 对象 XMLHttpRequest:



要获取更多 Jerry 的原创技术文章,请关注公众号"汪子熙":



发布于: 2021 年 05 月 23 日阅读数: 6
用户头像

Jerry Wang

关注

个人微信公众号:汪子熙 2017.12.03 加入

SAP成都研究院开发专家,SAP社区导师,SAP中国技术大使。

评论

发布
暂无评论
谣言粉碎机 - 极短时间内发送两个Odata request,前一个会自动被cancel掉?