Home  >  Article  >  Web Front-end  >  JavaScript asynchronous method queue chain implementation code analysis_javascript skills

JavaScript asynchronous method queue chain implementation code analysis_javascript skills

WBOY
WBOYOriginal
2016-05-16 18:25:401054browse

This method is described in more detail in "Javascript Design Patterns". To implement chain calls of methods, you only need to have the methods defined in the prototype return references to the instance objects that call these methods. Take a look at this code in the book:

Copy the code The code is as follows:

(function() {
function _$(els) {
this.elements = [];
for (var i = 0, len = els.length; i < len; i) {
var element = els[i];
if (typeof element == 'string') {
element = document.getElementById(element);
}
this.elements.push(element);
}
};
_$.prototype = {
each: function(fn) {
for ( var i = 0, len = this.elements.length; i < len; i ) {
fn.call(this, this.elements[i]);
}
return this;
},
setStyle: function(prop, val) {
this .each(function(el) {
el.style[prop] = val;
});
return this;
},
show: function() {
var that = this;
this.each(function(el) {
that.setStyle('display', 'block');
});
return this;
},
addEvent: function(type, fn) {
var add = function(el) {
if (window.addEventListener) {
el.addEventListener(type, fn, false);
}
else if (window.attachEvent) {
el.attachEvent('on' type, fn);
}
};
this.each(function(el) {
add(el);
});
return this;
}
};
window.$ = function() {
return new _$(arguments);
};
})();

As you can see, each method ends with "return this", which will pass the object of the calling method to the next one in the chain method. However, if the data we want to operate is obtained through an asynchronous request, how to maintain the chain of method calls? Dustin Diaz provides us with a way to ensure chained method calls. He is also one of the authors of the book "Javascript Design Patterns".
He first constructed a Queue object, namely:
Copy code The code is as follows:

function Queue() {
// store your callbacks
this._methods = [];
// keep a reference to your response
this._response = null;
// all queues start off unflushed
this._flushed = false;
}
Queue.prototype = {
// adds callbacks to your queue
add: function(fn) {
// if the queue had been flushed, return immediately
if (this._flushed) {
fn(this._response);
// otherwise push it on the queue
} else {
this ._methods.push(fn);
}
},
flush: function(resp) {
// note: flush only ever happens once
if (this._flushed) {
return;
}
// store your response for subsequent calls after flush()
this._response = resp;
// mark that it's been flushed
this._flushed = true ;
// shift 'em out and call 'em back
while (this._methods[0]) {
this._methods.shift()(resp);
}
}
};

Then use it as a tool to build our async method queue chain. With this tool, it is easy to build a jQuery plugin that fetches content from the server and appends it to a selector.
Copy code The code is as follows:

(function($) {
$.fn .fetch = function(url) {
var queue = new Queue;
this.each(function() {
var el = this;
queue.add(function(resp) {
$(el).html(resp);
});
});
$.ajax({
url: url,
dataType: 'html',
success: function(html) {
queue.flush(html);
}
});
return this;
};
})(jQuery);

In this way, we can get the content asynchronously and continue our chain of calls.
Copy code The code is as follows:

$("
")
.fetch('/server/navigation.html')
.addClass('column')
.appendTo('#side');

Viewdemo page to see the effect.
What to do if there are many items in a queue waiting to be operated on the server-side response? The author constructed such a method, which is worth reference:
Copy code The code is as follows:

function fetchTweet(url) {
this.queue = new Queue;
this.tweet = "";
var self = this;
ajax(url, function(resp ) {
self.tweet = resp;
self.queue.flush(this);
});
}
fetchTweet.prototype = {
linkify: function() {
this.queue.add(function(self) {
self.tweet = self.tweet.replace(/b@(w{1,20}b/g, '$1');
} );
return this;
},
filterBadWords: function() {
this.queue.add(function(self) {
self.tweet = self.tweet.replace(/ b(fuck|shit|piss)b/g, "");
});
return this;
},
appendTo: function(selector) {
this.queue. add(function(self) {
$(self.tweet).appendTo(selector);
});
return this;
}
};

In this way, we can call it in the following way:
Copy the code The code is as follows:

fetchTweet(url).linkify().filterBadWords().appendTo('#status');

At this point, we already know how to implement asynchronous method chain calling, but in " Some questions raised by some comments at the bottom of Asynchronous method queue chaining in JavaScript> are worth thinking about. The plug-in $.fn.fetch only needs to append the returned content to the element. Is Queue necessary? Moreover, $.fn.load in jQuery can be completely implemented. If only one callback function is used in Queue, it can be written like this:
Copy code The code is as follows:

(function($) {
$.fn.fetch = function(url) {
var queue = new Queue;
this.each( function() {
var el = this;
$.ajax({
url: url,
type: 'get',
dataType: 'json',
success: function(resp) {
$(el).html(resp['text1']);
}
});
});
return this;
};
})(jQuery);

What do you think?
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn