背??景有时我们可以在Chrome开发者工具的网络选项卡中观察到SAPUI5应用程序会发出一些状态为“取消”的OData请求。下图中的第五个请求。之前有一句似是而非的说法:如果在很短的时间内发送了两个OData请求,第一个会自动取消。从字面上看,有两点值得深思:1、取消,谁取消的?UI5框架还是Chrome?2、“极短”,极短是多短?我用代码在for循环中一共发送了10个OData请求:无论是同步还是异步,都没有取消请求。10个同步请求:10个异步请求:即使发送100个请求,也不会取消任何请求:验证结果,前面的语句“在很短的时间内发送两个OData请求,第一个会自动取消"是真的不正确。那么回到本文第一张图观察到的cancel场景,是什么原因呢?观察生成被取消的OData请求的应用程序代码,观察在第523行有这个刷新操作:在这个方法的第601行,bChangeDetected变量为真,调用了abortPendingRequest。abortPendingRequest的注释已经把问题说的很清楚了。什么情况会导致AbortPendingRequest?直接用ChromeDeveloperTools的全文搜索得到答案:OData模型的三个API:filter,sort,refresh下面是同事李奔的进一步补充。出现这种现象的原因和条件的问题1.在哪里可以看到这种取消现象?在我们的livesearch功能上,如果你输入的速度快或者正常,你会看到很多之前的输入请求都会被取消:如果输入慢一点就不会:真的是慢的原因吗?仔细观察网络发现,真正的原因是之前的网络还处于pending状态的时候,如果继续输入发起的请求,最后的请求就会被取消:继续研究,这是在哪做的?SAPUI5的OData框架中有这样一种实现:在ODataModel.js中维护了一个http请求的pending列表,在这个列表中缓存了已经发送但没有收到响应的请求对象:每次一个OData请求每次发起ODataModel的_request()方法都会被调用,该方法会将当前请求添加到pendinglist中,并通过wrap方法封装回调函数,保证缓存的request对象在调用时先从pendinglist中移除response返回Remove:每次对ODataModel发起过滤、排序、刷新操作时,都会检查是否有待处理的请求对象。如果有未完成的请求,中止:回答上面的问题,什么情况下会出现这种现象?1.连续请求在同一个ODataModel实例上发出,因为pendinglist是缓存在这一层的。2、之前的Http请求的网络还处于pending状态。3.阅读ODataModel的代码和观察到的现象,在ODataModel上发起过滤、排序或刷新时。为什么可以通过在OData请求对象上发起中止调用来取消底层网络调用?简单的说,UI5中的ODataRequest对象就是底层AjaxRequest对象XmlHttpRequest的代理。在ODataModel的_submit方法中:具体实现是在UI5中使用了第三方库datajs,datajs最终会调用浏览器底层的http对象XMLHttpRequest:
