谣言粉碎机 - 极短时间内发送两个Odata request,前一个会自动被cancel掉?
背景
有時(shí)我們能在Chrome開發(fā)者工具的Network tab里觀察到SAP UI5應(yīng)用會發(fā)出某些狀態(tài)為"取消"的OData請求。如下圖第五個(gè)請求。
之前有一種似是而非的說法:極短時(shí)間內(nèi)發(fā)送兩個(gè)OData請求,則第一個(gè)會自動被cancel掉。
這個(gè)說法從字面上看,有兩點(diǎn)值得推敲:
1. cancel掉,被誰cancel掉?UI5框架還是Chrome?
2. “極短”,多短算極短?
我用代碼在for循環(huán)里一共發(fā)10個(gè)OData請求:
無論是同步還是異步,都沒有任何的請求被cancel。
10個(gè)同步請求:
10個(gè)異步請求:
就算發(fā)100個(gè)request都不會有一個(gè)request被cancel:
驗(yàn)證結(jié)果,之前的說法“極短時(shí)間內(nèi)發(fā)送兩個(gè)OData request,前一個(gè)會自動被cancel掉”是錯(cuò)誤的。
那再回到本文第一張圖觀察到的cancel的場景, 原因究竟是什么?
觀察產(chǎn)生了被取消的OData請求的應(yīng)用代碼,觀察到第523行有這個(gè)refresh操作:
在這個(gè)方法的第601行,bChangeDetected變量為true導(dǎo)致abortPendingRequest的調(diào)用。
abortPendingRequest的注釋已經(jīng)很清楚地說明問題了。
什么情況下會導(dǎo)致AbortPendingRequest? 直接使用Chrome開發(fā)者工具的全文搜索得到答案:OData model的三個(gè)API: filter, sort, refresh
下面是我的同事Li Ben的進(jìn)一步補(bǔ)充。
關(guān)于這個(gè)現(xiàn)象發(fā)生的原因和條件的問題
1. 在哪里可以看到這個(gè)cancel現(xiàn)象?
在我們的live search功能上,如果輸入較快或者正常速度輸入,會看到前面很多輸入請求都會被cancel掉:
如果輸入較慢則不會:
真的是快慢的原因嗎?
仔細(xì)觀察network發(fā)現(xiàn),真正的原因是當(dāng)上一次的network還處于pending狀態(tài)的時(shí)候,繼續(xù)輸入發(fā)起的請求就會cancel掉上一次的請求:
繼續(xù)深究, 這是在哪里做到的?
在SAP UI5的OData框架里面有這樣的實(shí)現(xiàn):
在ODataModel.js中維護(hù)了一個(gè)http request的pending list,將已經(jīng)發(fā)送但是還沒有收到響應(yīng)的request對象都緩存在這個(gè)列表中:
每次發(fā)起OData請求的時(shí)候都會調(diào)用ODataModel的_request()方法,這個(gè)方法會把當(dāng)前的request加到pending list中,并且通過一個(gè)wrap method包裝回調(diào)函數(shù),確保在響應(yīng)返回的時(shí)候首先把緩存的request對象從pending list中拿掉:
每次在OData Model上發(fā)起filter, sort, refresh操作的時(shí)候,都會檢查是否存在pending的request對象,如果存在未完成的請求,abort掉它:
回答上面的問題,在什么情況下會發(fā)生這種現(xiàn)象?
1. 同一個(gè)ODataModel的instance上發(fā)出的連續(xù)請求,因?yàn)閜ending list是緩存在this級別上面的。
2. 前一個(gè)Http請求的network還處于pending status的時(shí)候。
3. 就讀ODataModel的代碼和觀察到的現(xiàn)象,在ODataModel上發(fā)起filter, sort或者refresh的時(shí)候。
為什么在OData的request對象上發(fā)起abort調(diào)用就可以取消底層的network call?
簡單的說,UI5里面的OData Request對象是底層的Ajax Request對象XmlHttpRequest的一個(gè)代理,在ODataModel的_submit方法中:
具體實(shí)現(xiàn)是UI5中利用了一個(gè)第三方的庫datajs,datajs最終會調(diào)用瀏覽器的底層http對象XMLHttpRequest:
要獲取更多Jerry的原創(chuàng)技術(shù)文章,請關(guān)注公眾號"汪子熙":
總結(jié)
以上是生活随笔為你收集整理的谣言粉碎机 - 极短时间内发送两个Odata request,前一个会自动被cancel掉?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在ABAP里实现条件断点的三种方式
- 下一篇: SAP ABAP的权限检查跟踪(Auth