Reputation: 13420
I have a function matcher
which is called every time a keyup event is sent.
This function belongs to a module which look like this (1).
what if another call is done before the fetching is completed?
How can I solve this problem in this module (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));
Upvotes: 3
Views: 538
Reputation: 33364
I'll take a different, probably overkill, approach and use the 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);
If the xhr is already resolved, the callback is immediately invoked, if not, it will be when the request completes : see jQuery.Deferred for more info.
And you would use it as
Matcher(1,console.log);
Matcher(2,console.log);
And a Fiddle http://jsfiddle.net/EWSAV/1/
Upvotes: 2
Reputation: 51201
As long as you run synchronous actions this should be no problem, because the events get executed in a timely manner.
However, you could add a second variable which indicates if a matching is in progress.
Something like this:
(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));
This code probably won't work, but I think you got the idea.
This approach however might require your asynchronous script to be in the same scope to have access to inProgress
. The better option might be to work with callbacks on the fetch:
userCollection.fetch({ success:function(){inProgress=false} });
Upvotes: 1
Reputation: 5179
According to Backbone.js documentation, fetch()
accepts a callback function to be called after a successful "fetch". So you can have a global variable indicating the state of the current "fetch". This is the basic idea, I think you can work your way from here
fetching = false;
//Event fired ->
if (!fetching ){
fetching = true;
..fetch({success: function(){fetching = false;}});
}
Upvotes: 0