An analysis of the asynchronous mode of node. js

Source: Internet
Author: User

Note: This article is a summary of node. JS's actual combat reading.

In the normal scripting language is synchronous, such as PHP, the way the server handles multiple requests is to parallel these scripts. Multitasking, multithreading, and more. But this approach also has a problem: every process or thread consumes a lot of system resources. If there is a way to maximize the CPU's computing power and available memory to reduce the waste of resources that would be great. In this way, our node. JS was born.

Previous node. JS simplest asynchronous Programming Case:

1 varFS = require (' FS ');2 3 varfile;4 5 Fs.open (6' Info.txt ', ' R ',7     function(err,handle) {8         varBUF =NewBuffer (100000);9 Fs.read (Tenhandle,buf,0,100000,NULL, One     function(err,length) { AConsole.log (buf.tostring (' UTF8 ', 0, length)); -Fs.close (Handle,function(){}); -     }); the          -     } -);
View Code

From this example, we can see the most callback functions used in asynchronous functions, which contain at least one parameter, that is, the state of the last operation (success or failure), and generally the second parameter, the result or information returned by the last operation (such as the file handle, database connection, queried data, etc.). Some callback functions may also contain more parameters. Assuming that the ERR represents the returned state parameter, the value of the parameter typically has the following conditions: 1.null: Indicates that the operation was successful, and there will be a return value if you want. 2. An instance of an Error object: It is often customary to add a Code field on an Error object and use the Message field to save the error message (Note: This way allows us to write more controllable non-blocking code). Optimization of the above code plus error handling:

1 varFS = require (' FS ');2 3 varfile;4 5 Fs.open (6' Info.txt ', ' R ',7     function(err,handle) {8         //The first method of error handling9         if(ERR)Ten         { OneConsole.log ("ERROR:" + Err.code + "(" +err.message+ ")"); A             return; -         } -         varBUF =NewBuffer (100000); the Fs.read ( -handle,buf,0,100000,NULL, -     function(err,length) { -         //The second method of error handling +         if(err) { -Console.log ("ERROR:" +err.code+ "(" +err.message+ ")"); +}Else{ AConsole.log (buf.tostring (' UTF8 ', 0, length)); atFs.close (Handle,function(){}); -         } -          -     }); -          -     } in);
View Code

However, in the process of asynchronous processing pay attention to the use of this and function scope changes, see the following code:

1 varFS = require (' FS ');2 3 functionFileObject () {4      This. FileName = ";5 6      This. file_exists =function(callback) {7Console.log ("About to open:" + This. FileName);8Fs.open ( This. FileName, ' R ',function(err,handle) {9             if(err) {TenConsole.log ("Can ' t open:" + This. FileName); One callback (ERR); A                 return; -             } -Fs.close (Handle,function(){}); theCallbackNULL,true); -         }); -     }; - } +  - varFO =NewFileObject (); +Fo.filename = ' Info '; AFo.file_exists (function(err,results) { at     if(err) { -Console.log ("ERROR:" +err.code+ "(" +err.message+ ")"); -         return; -     } -Console.log ("File exists!!!"); -});
View Code

We thought the output should be:

About to Open:info

Can ' t Open:info

But in fact it does:

About to Open:info

Can ' t open:undefined

Error:enoent (ENOENT, open ' G:\nodejs\info ')

What is this for? In our understanding, most of the time, when a function is nested in another function, he automatically inherits the scope of the parent function, and thus can access all the variables. But why does our nested callback function not show what we think is the output?

This problem is due to the This keyword and the asynchronous callback function itself. When we call the Fs.open function, he initializes himself and then invokes the underlying operating system function (in our code, which opens the file), inserts the callback function into the node. JS event queue, returns to the File_exists function immediately after execution, and exits. When Fs.open completes the task, node calls the callback function, but at this point, the function no longer has the inheritance of the class FileObject, so the callback function will re-assign the new this pointer, in this process we lose our fileobject this pointer, so we can not visit Ask us about our file_name. But in this process, the scope of the callback function remains. This is related to Nodejs's event pattern (reference: http://nodejs.org/docs/latest/api/events.html), which is also an important feature of Nodejs, and we don't say much now. The most common solution to this error is to save the missing this pointer in a variable, and let's rewrite

1  This. file_exists =function(callback) {2         //use a variable to store the this pointer3         varSelf = This;4Console.log ("About to open:" +self.filename);5Fs.open ( This. FileName, ' R ',function(err,handle) {6             if(err) {7Console.log ("Can ' t open:" +self.filename);8 callback (ERR);9                 return;Ten             } OneFs.close (Handle,function(){}); ACallbackNULL,true); -         }); -};
View Code

OK, so our output is the same as we imagined, we must not forget this change when writing code, otherwise there may be a lot of bug =.

OK, let's go on. We all know that node runs in a single thread, using event polling to invoke external functions and services. It inserts a callback function into the event queue to wait for a response, and executes the callback function as soon as possible. OK, let's take a look at a function that functions as a cross-element of two arrays:

1 functioncompute_intersection (arr1,arr2,callback) {2     varResults = [];3      for(vari = 0; i<arr1.length; i++)4          for(varj = 0; j<arr2.length; J + +){5             if(Arr1[i] = =Arr2[j]) {6 Results.push (Arr1[i]);7 Bareak;8             }9         }TenCallbackNULL,true); One}
View Code

When the elements in my array are particularly large, the function consumes a lot of computational time. We know that in single-threaded mode, node. JS can only do one thing at a time, so this amount of time will be a problem. Some other computational hashes, for example. Abstract (Digest) or other time-consuming operations can cause the application to be in suspended animation. So node. JS is not suitable for compute servers, NODEJS is more suitable for common network tasks, such as those that require a large number of I, O or requests to other services, and if a large number of compute servers are needed, the first solution is to migrate these operations to other servers. It is then called remotely with Nodejs. But if you only perform this task occasionally, then there is a second workaround, which is to take advantage of the Nexttick method of the global object process, which is to tell the system that I do not take control, and that you execute the function I gave you when you are free.

Well, some traps in async and basically have been introduced, welcome to add.

An analysis of the asynchronous mode of node. js

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.