我有一个函数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));
我将采用一种不同的方法,可能过于夸张,并使用collection.fetch
返回的jqXHR对象。
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/
只要运行同步操作,这应该没有问题,因为事件会及时执行。
但是,您可以添加第二个变量,指示是否正在进行匹配。
类似这样的东西:
(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} });
根据Backbone.js文档,fetch()
接受在成功"获取"后调用的回调函数。因此,您可以有一个全局变量来指示当前"fetch"的状态。这是基本的想法,我认为你可以从这里开始工作
fetching = false;
//Event fired ->
if (!fetching ){
fetching = true;
..fetch({success: function(){fetching = false;}});
}