謠言粉碎機-極短時間內傳送兩個Odatarequest,前一個會自動被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的原創技術文章,請關注公眾號”汪子熙”或者掃描下面二維碼:
相關文章
- SAP UI5 謠言粉碎機:極短時間內傳送兩個Odata請求,前一個會自動被cancel掉嗎UI
- 兩個時間戳的時間差時間戳
- 短視訊系統原始碼,直播間實現彈幕的自動傳送原始碼
- JS判定一個給定的時間在某個時間範圍內JS
- JavaScript比較兩個時間JavaScript
- 兩個技術小錯誤會毀掉一場風暴事件事件
- e語言自動傳送訊息【win11】
- CORS跨域時,為何會傳送兩次請求?CORS跨域
- 寫程式碼被大語言模型坑之使用LocalDateTime比較兩個時間差了幾天模型LDA
- What?一個 Dubbo 服務啟動要兩個小時!
- JavaScript計算兩個時間點之間的時間差JavaScript
- vscode輸入中文標點符號自動覆蓋前一個字元以及彈出兩個符號VSCode符號字元
- 當前時間是否大於某個時刻
- connection事件當有資料傳送過來時會被觸發事件
- 『動善時』JMeter基礎 — 6、使用JMeter傳送一個最基礎的請求JMeter
- 應用機器學習時被遺忘的兩個步驟機器學習
- android短影片開發,兩個ViewPager聯動效果AndroidViewpager
- Springboot 自動傳送郵件Spring Boot
- JS判定一個給定的時間區間在哪些時間段範圍內JS
- Windows開機自動同步時間Windows
- JavaScript 計算兩個時間相差天數JavaScript
- Dynamics CRM使用計算欄位自動計算兩個時間欄位的天數差
- 沒時間學Python,配置個RPA軟體機器人自動做事試試Python機器人
- oracle計算兩個日期的時間差時分秒Oracle
- 手機直播原始碼,每隔一段時間自動重新整理一次內容原始碼
- 如果一個標籤元素同時出現兩個class屬性,兩個class都會生效嗎?為什麼?
- vue兩個元件間值的傳遞或修改方式Vue元件
- python+resuests 傳送請求,結果中如果欄位的值是 null 就會被 json 自動過濾掉,請問如何才能不被過濾PythonNullJSON
- 如何使用jMeter傳送兩個邏輯上相關的HTTP請求JMeterHTTP
- 當一個 Pod 被排程時,Kubernetes 內部發生了什麼?
- Java傳送郵件必帶超時時間配置Java
- 三星被曝出現漏洞,手機會隨機傳送照片給別人隨機
- 如何設計一個秒殺系統-許令波-極客時間
- 牛逼!在Vue3.5中僅僅2分鐘就能封裝一個自動cancel的fetch函式Vue封裝函式
- 西遊記團隊中如果需要裁掉一個人,會先裁掉誰?
- 釘釘機器人自動關聯 GitHub 傳送 approval prs機器人GithubAPP
- [開源&分享]一個用於微控制器IAP自動傳送的串列埠助手,上位機,使用Python+tkinter製作串列埠Python
- 廢掉一個人最隱蔽的方式,是讓他忙到沒時間成長