谣言粉碎机 - 极短时间内发送两个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的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:


谣言粉碎机 - 极短时间内发送两个Odata request,前一个会自动被cancel掉?的更多相关文章
- chrome 浏览器的预提取资源机制导致的一个请求发送两次的问题以及ClientAbortException异常
调查一个 pdf 打印报错: ExceptionConverter: org.apache.catalina.connector.ClientAbortException: java.net.Sock ...
- axios发送两次请求原因及解决方法
axios发送两次请求原因及解决方法 最近Vue项目中使用axios组件,在页面交互中发现axios会发送两次请求,一种请求方式为OPTIONS,另外一种为自己设置的. 如图: 什么是CORS通信? ...
- JavaScript中一个方法同时发送两个ajax请求问题
今天在做项目中遇到一个问题,大概是在一个jsp页面同时有一个select下拉搜索条件框和一个Bootstrap表格展示列表.这两个都要通过ajax向后台拿数据,而且要在页面加载时完成.当时的做法是: ...
- vue使用axios发送请求,都会发送两次请求
vue 使用axios,每次的请求都会发送两次,第一次的请求头为options CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sha ...
- nginx配置跨域之后每次访问会发送两次请求
公司项目从前后端不分离转到前后端分离 首先遇到的问题就是前后端分离的时候跨域的问题 但是当跨域成功配置并且能访问成功的时候发现 每次客户端的请求都会发送两次 第一次是OPTIONS的请求,然后才是正常 ...
- PHP实现无限极分类的两种方式
无限极分类说简单点就是一个类可以分成一个分子类,然后一个子类又可以分另一个子类这样无限分下去,就是好象windows可以新建一个文件夹,然后在这个文件夹里又可以建一个文件夹,PHP要实现无限极分类有两 ...
- axios发送两次请求问题解决
在使用axios的过程中,会发送两次请求. 看了下是因为有一个请求是OPTIONS来判断跨域的时候让不让发送请求的. 这个不算是一个bug,但是发送两个请求着实让人看着不舒服.于是修改了下,原来的请求 ...
- SqlServer数据库同时备份到两台服务器上(并自动删除过期文件)
数据库同时备份到两台服务器上(并自动删除过期文件) 举例 :(本地)服务器A: IP :192.168.1.1 (远程)服务器B: IP :192.168.1.2 数据库版本:SqlServer200 ...
- javaBean默认接受request发送过来的数据,根据键自动设置属性
javaBean默认接受request发送过来的数据,根据键自动设置属性
随机推荐
- Python Flask框架之页面跳转
IDE用的PyCharm(还是vs强大啊). 项目结构: 2:页面: <!doctype html> <html lang="zh"> <head&g ...
- Mysql5.7不区分大小写设置
1.编辑mysql配置文件my.cnf 2.在[mysqld]下添加一行 lower_case_table_names=1#0表示区分大小写,1表示不区分大小写
- 2.5 References & Borrowing
Here is how you would define and use a calculate_length function that has a reference to an object a ...
- JS中String()与.toString()的区别
1..toString()可以将所有的的数据都转换为字符串,但是要排除null 和 undefined 例如将false转为字符串类型 <script> var str = false.t ...
- 60分钟内从零起步驾驭Hive实战学习笔记(Ubuntu里安装mysql)
本博文的主要内容是: 1. Hive本质解析 2. Hive安装实战 3. 使用Hive操作搜索引擎数据实战 SparkSQL前身是Shark,Shark强烈依赖于Hive.Spark原来没有做SQL ...
- flex buider 4.6 打开设计模式(designer)时提示内存不足错误的解决办法
先申明,此方法只适用于flex builder 4.6及以下版本, flex builder 4.7以后已经完全取消了designer功能,是没有办法补救的. 1. 首先下载APE文件,这个文件好像是 ...
- ZOJ 1610——Count the Colors——————【线段树区间替换、求不同颜色区间段数】
Count the Colors Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu Subm ...
- ebiao 报表工具使用入门
一.ebiao简价 e表是一个功能强大的Web报表工具,可使复杂报表的设计简单化,避免了大量的复杂SQL编写以及编程来准备数据,报表设计的效率大大提高.e表分为e表 for .NET和e表 for J ...
- 网页设计,Access入门 2010,语文
Access入门 2010(select查询) order by(按升序排列)?+desc(按降序排列) group by(进行分组,下一行只能用having) sum(数值总数)?+as?(新字段的 ...
- C# 调用者信息获取
做日志组件时,常常会记录调用者信息,通常都是通过反射来获取相应信息.不过.Net 4.5引入了三个新的特性,即CallerFilePathAttribute,CallerLineNumberAttri ...