使用隊列控制多個請求訪問一個異步方法

  以前在項目進入測試階段的時候,測試部給發了一個bug,大體是在搜索的時候搜索出來的東西和實際的不符合。ajax

  因而我去翻代碼,原來問題是搜索的時候每次鍵盤按下都會進行一次搜索,可是搜索時間是異步的,這就致使了上一次搜索還沒結束下一次搜索就有開始了。代碼的執行就想是一鍋粥,亂成一團。搜索的結果天然是不可能準確的了。數組

  事實上,異步代碼一旦調用頻繁後,要麼回調滿地圖跑,要麼這些代碼不要求有前後,規律。我見過一些代碼,全部的請求都用異步,有時候兩三個方法同時請求一個方法的時候,就會出現變量賦值錯誤,代碼執行混亂等問題。。。。話題扯遠了,回到搜索的問題,若是要處理這種問題該怎麼辦呢?我一直思考,都沒有想出什麼好辦法。異步

  這時候就體現出了,經驗與知識的重要性。我遍尋無果後,便去問了同事和經理,通過他們的指導,算是有了一些頭緒。學習

  使用隊列來控制搜索的次數與條件。測試

  

            //隊列
            Queue:function(){
                var arr = [];
                //入隊
                this.push = function (item) {
                    arr.push(item);
                    return true;
                };
                //出隊
                this.shift = function () {
                    return arr.shift();
                };
                //獲取隊首
                this.getHead = function () {
                    return arr[0];
                };
                //獲取隊尾
                this.getTail = function () {
                    return arr[arr.length - 1];
                };
                //刪除數組固定位
                this.splice = function (start,end) {
                    arr.splice(start, end);
                };
                //清空數組
                this.clear = function () {
                     arr=[];
                };
                //獲取數組長度
                this.getLength = function () {
                    return arr.length;
                };
            }

  搜索的時候,按鈕第一次被按下時,將搜索條件push到隊列裏,並調用搜索方法。非第一次直接就push到隊列裏。this

  搜索方法執行時,先取隊尾的搜索條件,校驗,將搜索條件附加到參數中。在成功返回的回調中獲取當前隊列的長度,若是隊列長度大於1,刪除除了隊尾的其他搜索條件,並遞歸執行搜索方法,不然就清空隊列。每次執行都會只剩下隊尾的一個或空,直到沒有再按下搜索條件,遞歸纔會終止。spa

     var queue=new Queue();
     //搜索點擊
     function onSearchClick(key){         
         if(queue.getLength==0){
            queue.push(key);
            search()
         }else{
            queue.push(key); 
         }
     }
     //搜索
     function search(){
         //獲取隊尾
         var key=queue.getTail();
         if(!key){
             $.ajax({
                ....
                data:{searchKey:key},//賦值搜索條件
                ....
                success:function(result){
                    var length=queue.getLength();
                    if(length>1){
                        //清空除隊尾的其他條件
                        queue.splice(0,length);
                        //遞歸調用
                        search();
                    }else{
                        //清空隊列
                        queue.clear();
                    }                    
                },             
            })
         }
     }
     
    //隊列
    Queue:function(){
        var arr = [];
        //入隊
        this.push = function (item) {
            arr.push(item);
            return true;
        };
        //出隊
        this.shift = function () {
            return arr.shift();
        };
        //獲取隊首
        this.getHead = function () {
            return arr[0];
        };
        //獲取隊尾
        this.getTail = function () {
            return arr[arr.length - 1];
        };
        //刪除數組固定位
        this.splice = function (start,end) {
            arr.splice(start, end);
        };
        //清空數組
        this.clear = function () {
            arr=[];
        };
        //獲取數組長度
        this.getLength = function () {
            return arr.length;
        };
    }

  如上完整的控制搜索代碼,在這裏還得說最開始個人思路是有的,可是代碼寫的很糟糕,基本沒有層次,邏輯也是處處亂串。原本我覺得能實現功能就是最好,直到一個經驗比較豐富的同事作了相似的功能,我撒了一眼,果真我仍是太菜了。因而參照同事的代碼結構結合本身的思路重構了一下,感受比以前的好多了。code

  這個事件讓我意識到本身仍是積累知識,積累經驗的時段。仍是須要不斷學習,咱們所處如逆水行舟,不進則退。blog

  若是有什麼寫的不對,或是改進的地方還望不吝賜教。遞歸

相關文章
相關標籤/搜索