The problems caused by asynchronous programming are not obvious in client-side Javascript, but as server-side Javascript is more and more widely used, a large number of asynchronous IO operations make this problem obvious. There are many different ways to solve this problem, and this article discusses a few, but doesn't go into depth. Everyone needs to choose a method that suits them according to their own situation.
This article introduces asynchronous programming in js to you in detail. The specific content is as follows
1 About asynchronous events
Events are the most important feature in JavaScript, and nodejs is designed to take advantage of the asynchronous nature of js. So let’s talk about the event mechanism here.
In a js file, if you want to run a certain function, there are two ways. One is to call it directly, such as foo(), and the second is to use events to trigger it. This function is also called a callback function, such as passing it to setTimeout function and onready attribute.
1. The event in the setTimeout function is asynchronous
setTimeout is essentially an asynchronous event, which is triggered when the delay time expires. However, sometimes (in fact, most of the time) it will not be executed according to the given delay time. First Look at the code below
var start = new Date(); setTimeout(function() { console.log('settimeout1:',new Date()-start); }, 500); while (new Date() - start < 1000) { console.log('in while'); } document.getElementById('test').addEventListener('click', function(){ console.log('test:',new Date()-start); }, false) for(var i=0;i<10000;i++){ console.log('in for'); } setTimeout(function(){ console.log('settimeout2: ',new Date()-start); },1000); /* 10214 in while index.jsp (第 19 行) 10000 in for index.jsp (第 25 行) settimeout1: 2263 index.jsp (第 16 行) settimeout2: 3239 index.jsp (第 28 行) test: 10006 index.jsp (第 22 行) test: 28175 index.jsp (第 22 行) test: 28791 index.jsp (第 22 行) test: 28966 index.jsp (第 22 行) */
According to normal understanding, the delay function should interrupt the while loop after 500 milliseconds, but in fact it does not. Moreover, when I clicked the div during the while loop and for loop, the test was not output immediately. The explanation given That is:
a) Event queue. When the setTimeout function is called, the callback function passed to it will be added to the event queue (the event has been initialized and in memory), and then the subsequent code will continue to be executed until no more code can be run (there is no normal running flow) (excluding asynchronous content such as event functions), a suitable event will be popped out from the event queue to run.
b) js is single-threaded, and the event handler will not run until the thread is idle.
2 The asynchrony of ordinary events is similar to setTimeout
Two promise objects and deferred objects
1. promise
Promise is a solution to the problem of too many nested callback functions in asynchronous programming such as ajax, which makes the code obscure and difficult to understand. Especially in nodejs, asynchronous is everywhere. Different frameworks implement promises. The following is the promise API in jquery.
The implementation principle of promise will not be discussed here. The principle will be introduced in another space.
Traditional ajax asynchronous programming is written like this (before jquery1.5):
$.get('url', function(){ $.get('url1', function(){ $.get('url2', function(){ }, 'json'); }, 'json'); }, 'json');
Writing code like this brings great difficulties to development and maintenance. Fortunately, after jquery1.5 introduced promises, you can write it like this:
$.ajax( "example.php" ) .done(function() { alert("success"); }) .fail(function() { alert("error"); }) .always(function() { alert("complete"); });
It looks obviously much simpler now.
2.deferred object
var nanowrimoing = $.Deferred(); var wordGoal = 5000; nanowrimoing.progress(function(wordCount) { var percentComplete = Math.floor(wordCount / wordGoal * 100); $('#indicator').text(percentComplete + '% complete'); }); nanowrimoing.done(function(){ $('#indicator').text('Good job!'); });
3. Worker object and multi-threading
4. Asynchronous script loading
1. The position of traditional scripts in the page
Scripts are divided into two broad categories: blocking and non-blocking. The blocking here refers to loading blocking rather than running blocking.
<!DOCTYPE html> <html> <head> <script src="headScript"></script> <script defer src="deferredScript"></script> </head> <body> <script async defer src="chatWidget"></script> <script async defer src="asyncScript"></script> </body> </html>
The above part of the code is relatively standard regarding the position of the script in a page. 1. The traditional unmodified headScript is a blocking script. Since the browser interprets and executes JavaScript from top to bottom, this Some script files will be executed at the beginning, and the DOM will not be rendered before execution is completed, but the css in the head tag will be loaded. 2. Scripts with defer attributes will be loaded at the same time as the DOM is rendered, but will not be executed until the DOM is rendered. Unfortunately, not all browsers support the defer attribute, so jquery (function) is created. This thing. 3. When both the async attribute and the defer attribute are present, defer will override async, but when async is provided alone, the script will be loaded and run during DOM rendering.
2. Programmable script loading
If you do not introduce js files into the page from the beginning, but dynamically load js scripts through user interaction, you can add them programmatically.
There are two ways for browsers to obtain server scripts. Ajax obtains and executes it through the eval function. The other is to insert the