This week did a small activity (http://aoqi.100bt.com/zt-2016duanzi/index.html), at the beginning of the not optimistic about demand, logic is written a piece of
Finally, all kinds of pits to fill, and also gained some experience and lessons, the following said here will use the $. Deferred;
About the basic use of deferred in jquery, Ruan Yi Feng Aunt already has the article to understand, the link is as follows:
Http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html
Let's talk about what's not mentioned here:
The trouble with the logic in the page is the rendering of the winning list, such as
The logic required here is:
1, to obtain the time, to determine whether there are activities over the polling time, no click, the page does not render
2, come over the time, judge whether to get to the winning list, get to the page to render the sub-stage, get not to render the previous stage of the page,
The previous phase of the page is still not getting to the back of the page, if the first stage is not rendered.
Suppose four pages corresponding to the winning list is 1.html, 2.html, 3.html, 4.html;
If there is time to judge the activity time is in the fourth stage, that is, the first three stages are over, our implementation of the logic or maybe
$.get (' 3.html '). Done (function(){ //Render Page}). Fail (function(argument) {$.get (' 2.html '). Done (function(argument) {//Render Page}). Fail (function(argument) {function(argument) {$.get (' 1.html '). Done (function(argument) {//Render Page}). Fail (function(argument) {//do not render pages }) } })})
This is very undesirable, in each of the different stages are nested once, and each request must wait for the last request to send out, too slow ...
So I changed it to something like the following.
var linkarr = [' 1.html ', ' 2.html ', ' 3.html ', ' 4.html '] $nav. Each (function(index, EL) { var $self = $ (this); $.get (index+ '. html '). Done (function (argument) { $self. Text (' winning list out ') }) . Fail (function (argument) { $self. addclass (' Graynav '). Text (' Please expect '); });
Can "parallel" to make multiple requests, it looks good, and then in the Add click Render Event, click on the different NAV rendering has come out of the corresponding award list, well, this is also logically required
$ ('. Acommon_nav '). Click (function(event) { if($ (this). Hasclass (' Graynav ') ) {returnfalse; } var i = $ (' Acommon_nav '). Index ($ (this)); function (data) { $inforWrap. html (data) });
At this point, we simply call the last available nav when the "concurrent" request is finished. That's great.
However, the installation of this type of writing, we can not determine whether the request has been completed, may need to maintain a global variable num, in each fail and done plus 1, when Num equals the number of messages to be sent before calling the function
varLinkarr = [' 1.html ', ' 2.html ', ' 3.html ', ' 4.html ']vari = 0; $nav. each (function(Index, EL) {var$self = $ ( This); if($self. attr (' xxx ') <=timenum) {//judged by Time is the end of the sign$.get (index+ '. html '). Done (function(argument) {i++; $self. Text (' The winning list came out '); if(i==LEN) { //doclickevent ()}}). Fail (function(argument) {i++; $self. addclass (' Graynav '). Text (' Please expect '); if(i==LEN) { //doclickevent () } }); }});
At this point has basically completed the logic, but the code is too rough, need to improve the next, use when to complete it ~
varLinkarr = [' 1.html ', ' 2.html ', ' 3.html ', ' 4.html '], Deferredarr= [];$('. Acommon_nav '). each (function(Index, EL) {var$self = $ ( This); if($self. attr (' xxx ') <=timenum) {//judged by Time is the end of the signDeferredarr.push ($.get (index+ '. html '). Done (function(argument) {$self. Text (' The winning list came out '); }). Fail (function(argument) {$self. addclass (' Graynav '). Text (' Please expect '); })}); $.when.apply (NULL, Deferredarr). Always (function(ARG) {$ ('. Acommon_nav:not (. Garynav) '). Last (). click ();})
At this time, seemingly complete the logic, but, after debugging found that sometimes do done, then fail and then always and then done, it seems that this order some nonsense ...
What we want to do, however, is to do or fail to execute always at first.
Found the reason is the binding order caused, so found two roads go,
The first, the done and fail logic are written in always, as follows
$.when.apply (null, Defferredarr). Always (function(ARG) { function( Index, Val) { val.done ( argument) { $self. Text (' winning list out '); }). Fail (function (argument) { $self. addclass (' Graynav '). Text (' Please expect '); }) }); $ ('. Acommon_nav:not (. Garynav) '). Last (). click ();})
It feels good, deferred's callback function is written a piece, maintenance is also happy.
But when the deferredarr inside only one element, found an error, good embarrassment, only a breakpoint to see,
It is found that the arguments in the always callback function is an array, the first one is the data returned by the request, the second is the return state, and the third is the deferred object of the request.
So we have to add a judgment, or add a try.catch wrapped with done and fail, the code is not affixed, is too fooled.
The second way, using SetTimeout's dark magic.
varLinkarr = [' 1.html ', ' 2.html ', ' 3.html ', ' 4.html '], Deferredarr= [];$('. Acommon_nav '). each (function(Index, EL) {var$self = $ ( This); if($self. attr (' xxx ') <=timenum) {//judged by Time is the end of the signDeferredarr.push ($.get (index+ '. html '). Done (function(argument) {$self. Text (' The winning list came out '); }). Fail (function(argument) {$self. addclass (' Graynav '). Text (' Please expect '); })}); $.when.apply (NULL, Deferredarr). Always (function(ARG) {setTimeout (function(argument) {$ ('. Acommon_nav:not (. Garynav) '). Last (). click (); },0)})
So the business was finished, and the crap was done.
jquery Deferred use Experience