What if the browser is suspended due to jQuery Ajax synchronization parameters?

Source: Internet
Author: User
Tags php code

The reason is that there are multiple similar asynchronous request actions on the page. Based on the principle of improving code reusability, I encapsulated a function named getData, which receives different parameters, only obtains data and returns the data. The basic logic is stripped out as follows:

 

The code is as follows: Copy code
Function getData1 () {var result;
$. Ajax ({
Url: 'P. Php ',
Async: false,
Success: function (data ){
Result = data;
            }
}); Return result;
}

Ajax here cannot be asynchronous. Otherwise, the result is not assigned a value when the function returns, and an error will occur. So I added async: false. It seems that there is no problem. I can call this function to obtain data normally.

The code is as follows: Copy code
$ ('. Btn1'). click (function () {var data = getData1 ();
Alert (data );
});

Next, we need to add another function. Because ajax requests are time-consuming, I need to have a loading effect on the page before sending the request, that is, display a GIF image that is being loaded, I think everyone has seen it. So my processing function becomes like this:

The code is as follows: Copy code
$ ('. Btn1'). click (function (){
$ ('. Loadingicon'). show (); var data = getData1 ();
$ ('. Loadingicon'). hide ();
Alert (data );
});

The loading image is displayed before the request, and hidden after the request is complete. It seems that there is no problem. To see the effect, my p. php code sleep for 3 seconds, as shown below:

<? Phpsleep (3); echo ('aaaaa');?>
However, I encountered a problem during running. The loading image didn't appear as expected when I clicked the button, and the page did not respond. After a long period of troubleshooting, the cause is found in async: false.

The rendering (UI) thread of the browser and js thread are mutually exclusive. Page rendering will be blocked when JavaScript time-consuming operations are executed. It is okay when we execute asynchronous ajax, but when we set it to synchronous request, other actions (the code after the ajax function and the rendering thread) will stop. Even if my DOM operation statement is in the previous sentence of the request, this synchronous request will "quickly" block the UI thread and not give it the execution time. This is why the code is invalid.

SetTimeout solves the blocking problem
Now that we understand where the problem is, we can find a specific solution. To prevent the thread from being blocked by synchronous ajax requests, I thought of setTimeout. I put the request code in sestTimeout, and asked the browser to restart a thread to operate. Isn't the problem solved? As a result, my code becomes like this:

 

The code is as follows: Copy code
$ ('. Btn2'). click (function (){
$ ('. Loadingicon'). show ();
SetTimeout (function (){
$. Ajax ({
Url: 'P. Php ',
Async: false,
Success: function (data ){
$ ('. Loadingicon'). hide ();
Alert (data );
                }
});
}, 0 );
});

The second parameter of setTimeout is set to 0, and the browser will execute it after a set minimum time. No matter how many days, run the command first.

The result loading image is displayed, !!! Why can't images be moved? I am a dynamic gif image. At this time, I quickly thought that although the synchronous request is delayed, the UI thread will still be blocked during its execution. This blocking is awesome, and even GIF images don't move. It looks like a static image.

Conclusion: it is obvious that setTimeout is not a permanent cure, which is equivalent to synchronizing requests "slightly" asynchronously. Next, it will be a nightmare of synchronization and thread blocking. Solution failed.

It's time to use Deferred.
JQuery introduced the Deferred object after version 1.5, providing a convenient generalized asynchronous mechanism. For more information, see this article by instructor Ruan Yifeng. So I used the Deferred object to rewrite the code, as shown below:

The code is as follows: Copy code


Function getData3 () {var defer = $. Deferred ();
$. Ajax ({
Url: 'P. Php', // async: false,
Success: function (data ){
Defer. resolve (data)
            }
}); Return defer. promise ();
}   
$ ('. Btn3'). click (function (){
$ ('. Loadingicon'). show ();
$. When (getData3 (). done (function (data ){
$ ('. Loadingicon'). hide ();
Alert (data );
});
});

We can see that async: false is removed from the ajax request, that is, the request is asynchronous. In addition, pay attention to this sentence in the success function: defer. resolve (data). The resolve method of the Deferred object can input a parameter of any type. This parameter can be obtained in the done method, so the data from the asynchronous request can be returned in this way.

So far, the problem has been solved. The Deferred object is so powerful and convenient that we can make good use of it.

All of my test code is as follows. If you are interested, you can test it:

The code is as follows: Copy code


<Button class = "btn1"> async: false </button> <button class = "btn2"> setTimeout </button> <button class = "btn3"> deferred </button>
<script>
Function getData1 () {var result;
$. Ajax ({
Url: 'P. Php ',
Async: false,
Success: function (data ){
Result = data;
            }
}); Return result;
    }
$ ('. Btn1'). click (function (){
$ ('. Loadingicon'). show (); var data = getData1 ();
$ ('. Loadingicon'). hide ();
Alert (data );
});
   
$ ('. Btn2'). click (function (){
$ ('. Loadingicon'). show ();
SetTimeout (function (){
$. Ajax ({
Url: 'P. Php ',
Async: false,
Success: function (data ){
$ ('. Loadingicon'). hide ();
Alert (data );
                }
});
}, 0 );
}); Function getData3 () {var defer = $. Deferred ();
$. Ajax ({
Url: 'P. Php', // async: false, success: function (data ){
Defer. resolve (data)
            }
}); Return defer. promise ();
    }   
$ ('. Btn3'). click (function (){
$ ('. Loadingicon'). show ();
$. When (getData3 (). done (function (data ){
$ ('. Loadingicon'). hide ();
Alert (data );
});
}); </Script>

 

PS: Has Firefox been optimized?

The above problems are tested in chrome and IE9 with the same conclusion. However, during my tests in Firefox, synchronous ajax does not block the UI thread, which means this problem does not exist at all. I tested it with other code. In Firefox, the js thread does block the UI thread, so there is no doubt. One possible guess is that Firefox has optimized the synchronization of ajax. What is the truth? I have not learned yet. Please advise if anyone knows this.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.