防抖動資料請求

mazhenxiao發表於2019-02-26

同頁面,多模組,同時請求同一介面

解決方案

  • list 為全域性暫時記錄
  • fun 為請求Promise事例
const list = {};
debounce(fun) { 
            
            return new Promise((resolve, reject) => { 
                let d = Date.now();
                list[d] = [resolve, reject];
                //console.log(list);
                if (!list["time"]) { 
                    list["time"] = true;
                    let type = null, data = [];
                    fun.then(d => { 
                        type = 0;
                        data = d;
                    })
                    .catch(e => { 
                        type=1
                    })
                    .finally(d => { 
                        for (let i in list) {
                            if (Array.isArray(list[i])) { 
                                list[i][type](data);
                            }
                        }
                        list = {};
                        
                    })
                    
                }
                
                
            })
            
}
複製程式碼

呼叫

效果是隻呼叫一次,返回多個結果

this.debounce(server.serverSearchNews({
            "page": {
                "maxResultCount": 20,
                "pageNo": 1,
                "pageSize": 5,
                "skipCount": 0
            }
        }));
this.debounce(server.serverSearchNews({
             "page": {
                 "maxResultCount": 20,
                 "pageNo": 1,
                 "pageSize": 5,
                 "skipCount": 0
             }
         }))
this.debounce(server.serverSearchNews({
             "page": {
                 "maxResultCount": 20,
                 "pageNo": 1,
                 "pageSize": 5,
                 "skipCount": 0
             }
         }));
this.debounce(server.serverSearchNews({
             "page": {
                 "maxResultCount": 20,
                 "pageNo": 1,
                 "pageSize": 5,
                 "skipCount": 0
             }
         }));
複製程式碼

出現問題

如果將 //console.log(list); 開啟則顯示正常,但是如果將其註釋則只成功1個或兩個,沒有找到具體原因,因為初步懷疑是時間戳做key因執行速度快幾乎同時,key重複造成的,所以改動程式碼,在時間戳部分加入 let d = Date.now() + (LIST["time"] || 0); 增加訪問惰性,解決問題,但是具體造成原因,有兩個懷疑點。

  1. =>箭頭函式將作用域過早執行類似[Date.now(),Date.now(),Date.now(),Date.now()] 得到結果是相同的。
  2. 執行速度過快,key值重複。

解決

 debounce(fun) { 
          
           return new Promise((resolve, reject) => { 
               let d = Date.now() + (LIST["time"] || 0);
               LIST[d] = [resolve, reject];
               LIST["time"] && clearTimeout(LIST["time"]);
               LIST["time"] = setTimeout(() => {
                   let type = null,
                       data = [];
                   fun.then(d => {
                           type = 0;
                           data = d;

                       })
                       .catch(e => {
                           type = 1
                       })
                       .finally(d=>{
                           console.log(LIST);
                           for (let i in LIST) {

                               if (Array.isArray(LIST[i])) {
                                   LIST[i][type](data);

                               }
                           }
                           LIST = {};

                       })
               })
             
           })
           
   }

   
let LIST = {};
複製程式碼

相關文章