如何在发送keyup事件时避免竞争条件

时间:2012-07-11 13:34:08

标签: javascript backbone.js

我有一个函数matcher,每次发送一个keyup事件时都会调用它。

此功能属于如下所示的模块(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));

3 个答案:

答案 0 :(得分: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/

答案 1 :(得分: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。更好的选择可能是在fetch上使用回调:

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

答案 2 :(得分:0)

根据Backbone.js documentationfetch()接受在成功“获取”后调用的回调函数。所以你可以有一个全局变量来指示当前“fetch”的状态。这是基本的想法,我认为你可以从这里开始工作

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