來自我的同僚,SAP成都研究院的架構師Li Ben。
在SAP CRM Fiori App的早期開發過程中,關于live search功能上有一個問題,就是有時候發現live search傳回的suggestion item并不完全比對我們輸入的search string, 比如正常情況輸入abcde,應該比對4個結果:

但是有時候輸入abcde,會比對更多的結果,發現裡面有些item并不比對abcde,他們隻能比對abcd:
問題分析
使用者輸入到abcd和abcde的時候,都向背景發出了請求查詢比對的結果,最後将結果顯示到suggestion item中。
App請求的發送有先後順序(先發abcd,再發abcde),但是響應處理是通過異步回調,這裡不能保證處理傳回結果的先後順序跟請求發送的順序一緻,在使用者輸入較快,或者背景處理需要一定時間的情況下,有可能第二個請求(abcde)先于第一個請求(abcd)傳回。造成的結果是使用者最後的輸入停留在abcde,而最後的傳回結果是比對的abcd(如上圖)。
改進方案
方法1 - Throttle: 函數節流
Throttle又叫函數節流,目标是防止短時間内對一些昂貴的函數做出重複調用。
實作思想是在第一次調用函數的時候做一個定時器,同時設定一個threshold時間(函數的真正邏輯在定時器的threshold時間之後才被定時器執行),在該threshold之内,如果該函數沒有被再次調用,就讓定時器執行該函數的邏輯代碼;如果threshold之内該函數被再次調用,取消上一次設定的定時器,重新生成一個新的定時器,讓真正的邏輯重新被推遲到threshold時間之後執行。例子:
代碼看上去還是很直覺的。
Throttle - 函數節流的更多介紹:
http://wiki.jikexueyuan.com/project/brief-talk-js/function-throttling.html方法2:Asynchronous Completion Token(ACT):
ACT最早是用來解決通信系統的多路信号的問題,就是不同的請求發出之後,接受響應的一端需要知道每個響應對應的原始請求是什麼。我們live search的問題類似,我們需要知道比對使用者最後輸入字元串的那個響應,本質上也是ACT問題的一種。
ACT實作思路簡單講,就是給每個請求和對應的響應配置設定一個唯一的token,響應傳回的時候校驗token,具體實作結合應用場景可能有所不同。
我在My Lead上為了驗證ACT簡單實作了一下:
(1) 定義兩個變量緩存響應和使用者的最終輸入:
(2) 在change事件觸發的方法裡,讓sLastInput保持跟使用者的輸入一緻。
(3) 如果緩存的響應裡面已經有了比對的結果,不需要送出請求,直接從緩存取,這裡我将使用者最終輸入的字元串作為validate token。
(4) 如果緩存裡面沒有比對的結果才送出請求,在響應傳回的callback裡面,緩存結果并校驗token:
ACT Pattern的更多介紹:
http://www.cs.wustl.edu/~schmidt/PDF/ACT.pdf這本書裡也講了ACT:
http://software-pattern.org/Book/29比較一下Throttle和Async Completion Token: