2012-07-11 123 views
3

我有一個功能matcher,每次發送按鍵事件時都會調用它。如何在發送按鍵事件時避免競爭條件

此功能屬於如下所示的模塊(1)。
如果在獲取完成之前完成另一個調用,該怎麼辦?
我該如何解決這個模塊(1)中的問題?


(1)

(function ($, UserCollection) { 

    var userCollection; 

    var matcher = function (request, response) { 
     if (!userCollection) { 
      userCollection = new UserCollection(); 
      userCollection.fetch(); 
     } else { 
      isMatched(request, response); 
     } 
    }; 

    return matcher; 
}(jquery, UserCollection)); 
+0

注意你的'matcher'功能(或者至少看起來是)全球。你能解釋一些嗎(如果需要,編輯問題)你想要什麼和發生什麼? – Utkanos 2012-07-11 13:42:52

+0

你可以用JavaScript進度條做這件事情http://www.knowledgebase.vunet.us/web/progressbar.html – 2012-07-11 13:43:52

+0

@Utkanos我修復了代碼。我想避免在'userCollection.fetch'運行並未完成時調用'matcher'函數。 – 2012-07-11 14:00:22

回答

2

你的工作方式,我會採取不同的,可能是矯枉過正,方法和使用jqXHR object returned by collection.fetch

var Matcher=(function($,UserCollection) { 

    var xhr=null, userCollection=null; 

    // matching against a defined ID for testing purpose 
    function isMatched(id) { 
     return userCollection.get(id); 
    } 

    // the request would be an ID in my example, 
    // and the callback is the function invoked when the collection is fetched 
    function matcher(request, callback) { 
     if (!xhr) { 
      userCollection = new UserCollection(); 

      // fetch returns a handy xhr object used for the deferred 
      xhr=userCollection.fetch(); 
     } 

     xhr.then(function() { 
      callback(isMatched(request)); 
     }); 
    }  

    return matcher; 

})(jQuery, UserCollection); 

如果XHR已經解決了,回調立即調用,如果沒有,請求完成時將是:看到jQuery.Deferred獲取更多信息。

你就可以使用它作爲

Matcher(1,console.log); 
Matcher(2,console.log); 

並有小提琴http://jsfiddle.net/EWSAV/1/

+0

感謝你的迴應時切換keyup事件的事件監聽器。它似乎是最好的一個。 「xhr.then」有什麼問題?因爲我得到'Uncaught TypeError:不能調用方法',那麼'未定義' – 2012-07-11 14:53:49

+0

@LorraineBernard如果你看看http://backbonejs.org/#Collection-fetch,它應該是jQuery用來表示Ajax請求的對象。我測試了jQuery 1.7.2和Backbone 0.9.2 – nikoshr 2012-07-11 14:58:17

+0

@nikoshr @LorraineBernard也許你想這樣做'$ .when(xhr).then(function(){...})'? – antonjs 2012-07-11 15:15:20

1

只要你運行的同步動作,這應該是沒有問題的,因爲該事件得到及時執行。

但是,您可以添加第二個變量,指出是否正在進行匹配。

事情是這樣的:

(function ($, UserCollection) { 

    var userCollection; 
    var inProgress = false; 

    var matcher = function (request, response) { 
     if (!inProgress){ 
      if (!userCollection) { 
       inProgress = true; 
       userCollection = new UserCollection(); 
       userCollection.fetch(); 
      } else { 
       isMatched(request, response); 
      } 
      // inProgress = false; - after your asynchonous code is executed 
     } 
    }; 

    return matcher; 
}(jquery, UserCollection)); 

此代碼可能不會工作,但我覺得你有這個想法。

但是,此方法可能需要您的異步腳本處於相同範圍才能訪問inProgress。更好的選擇可能與上獲取回調的工作:

userCollection.fetch({ success:function(){inProgress=false} }); 
0

Backbone.js documentationfetch()接受一個回調函數後成功「取」被調用。所以你可以有一個全局變量指示當前「獲取」的狀態。這是基本的想法,我想你可以從這裏

fetching = false; 
//Event fired -> 
if (!fetching){ 
fetching = true; 
..fetch({success: function(){fetching = false;}}); 
}