Home  >  Article  >  Web Front-end  >  My Node.js learning path (3) - node.js functions, callbacks, synchronous and asynchronous code and event loop_node.js

My Node.js learning path (3) - node.js functions, callbacks, synchronous and asynchronous code and event loop_node.js

WBOY
WBOYOriginal
2016-05-16 16:42:352011browse

1. The role of node.js,

The meaning of I/O, (I/O is the abbreviation of input/output, such as: type text on the keyboard, input, see the text display output on the screen. Move the mouse, and see the movement of the mouse on the screen. Terminal input, and the output seen, etc.)

The problem that node.js wants to solve is (processing input, input, high concurrency. For example, there may be millions of players in an online game, and there will be millions of inputs, etc.) (Categories that node.js is suitable for: when Node.js is best suited when the application needs to send and receive data over the network. This may be a third-party API, a networked device, or real-time communication between the browser and the server)

The meaning of concurrency, (the term concurrency describes things that happen at the same time and may interact with each other. Node's evented I/O model allows us to not worry about interlocking and concurrency, which are common in multi-threaded asynchronous I/O question)

Demo network I/O

Js code

var http = require('http'), 
  urls = ['www.baidu.com','www.10jqka.com.cn','www.duokan.com']; 
function fetchPage(url){ 
  var start = new Date(); 
  http.get({host:url},function(res){ 
    console.log("Got response from:" + url); 
    console.log("Request took:",new Date() - start, "ms"); 
  }); 
} 
for(var i=0; i<urls.length; i++){ 
  fetchPage(urls[i]); 
} 

Named, node.js
We run node node.js
in the terminal Output:

We ask node.js to access three URLs and report the response received and the time it took.
We can see that the two output times are different. Affected by various factors, the time to resolve DNS requests, server busy procedures, etc.

Why JavaScript is an event-driven language
JavaScript is architected around events originally associated with the Document Object Model (DOM). Developers can do things when events occur. These events include the user clicking on an element, the page completing loading, etc. Using events, developers can write event listeners that are triggered when an event occurs.

2. Callback
1. What is a callback
2. Analyzing callbacks

A callback refers to passing a function as an argument to another function and is usually called after the first function completes.

Example: Such as the hide() method in jquery,
Js code

1,$("p").hide('slow'); 
2,$("p").hide('slow',function(){alert("The paragraph is now hidden")}); 

Callbacks are optional,
1 no need for callback
2. There is a callback. When the paragraph is hidden, it will be called and an alert prompt will be displayed.

So you can see the difference between code with and without callbacks
Js code

$("p").hide('slow'); 
alert("The paragraph is now hidden");//1 
 
$("p").hide('slow',function(){alert("The paragraph is now hidden")});//2 

1, there is no callback, and the execution order is the same. However, we can see that the p paragraph is not completely hidden, and the alert comes out
2. There is a callback, and the execution is in alert
after hide is completed.
Analyzing callbacks
Js code

function haveBreakfast(food,drink,callback){ 
  console.log('Having barakfast of' + food + ', '+ drink); 
  if(callback && typeof(callback) === "function"){ 
    callback(); 
  } 
} 
 
haveBreakfast('foast','coffee',function(){ 
  console.log('Finished breakfast. Time to go to work!'); 
}); 


Output:

Having barakfast of foast,coffee
Finished breakfast. Time to go to work!

Here is a function created with three parameters. The third parameter is callback. This parameter must be a function.
The haveBreakfast function logs what is eaten to the console and then calls the callback function passed to it as a parameter.

How to use callbacks in Node.js

Example of using filesystem module to read file contents from disk in node.js

Js code

var fs = require('fs'); 
 
fs.readFile('somefile.txt','utf8',function(err,data){ 
  if(err) throw err; 
  console.log(data); 
});

The result is: the content in somefile.txt.
1. The fs (filesystem) module is requested for use in scripts
2. Provide the file path on the file system as the first parameter to the fs.readFile method
3. The second parameter is utf8, which represents the encoding of the file
4. Provide the callback function as the third parameter to the fs.readFile method
5. The first parameter of the callback function is err, which is used to save the error returned when reading the file
6. The second parameter of the callback function is to save the data returned by reading the file.
7. Once the file is read, the callback will be called
8. If err is true, an error will be thrown
9. If err is false, then the data from the file can be used
10. In this example, the data will be logged to the console.

Another one, the http module, the http module allows developers to create http clients and servers.

Js code

var http = require('http'); 
 
http.get({host:'shapeshed.com'},function(res){ 
  console.log("Got response:" + res.statusCode); 
}).on('error',function(e){ 
  console.log("Got error:" + e.message); 
 
}); 

Result: Got response:200
1. Request the http module for use in scripts
2. Provide two parameters to the http.get() method
3. The first parameter is the options object. In this example, requesting the homepage of shapeshed.com
4. The second parameter is a callback function that takes the response as a parameter
5. When the remote server returns the response, the callback function will be triggered.
6. Record the response status code in the callback function. If there is an error, you can record it.

Next, let’s look at 4 different I/O operations happening, and they all use callbacks

Js code

var fs = require('fs'), 
  http = require('http'); 
 
http.get({host:'www.baidu.com'},function(res){ 
  console.log("baidu.com"); 
}).on('error',function(e){ 
  console.log("Got error:" + e.message); 
 
}); 
 
fs.readFile('somefile.txt','utf8',function(err,data){ 
  if(err) throw err; 
  console.log("somefile"); 
}); 
 
http.get({host:'www.duokan.com'},function(res){ 
  console.log("duokan.com"); 
}).on('error',function(e){ 
  console.log("Got error:" + e.message); 
 
}); 
 
fs.readFile('somefile2.txt','utf8',function(err,data){ 
  if(err) throw err; 
  console.log("somefile2"); 
}); 

 我们能知道哪个操作先返回吗?
猜测就是从磁盘上读取的两个文件先返回,因为无需进入网络,但是我们很难说哪个文件先返回,因为我们不知道文件的大小。对于两个主页的获取,脚本要进入网络,而响应时间则依赖于许多难以预测的事情,Node.js进程在还有已经注册的回调尚未触发之前将不会退出。回调首先解决不可预测性的方法,他也是处理并发(或者说一次做超过一件事情)的高效方法。
下面是我执行的结果


  
 同步和异步代码 

先看代码,同步(或者阻塞)代码

Js代码 

function sleep(milliseconds){ 
  var start = new Date().getTime(); 
  while((new Date().getTime() -start) < milliseconds){ 
 
  } 
} 
function fetchPage(){ 
  console.log('fetching page'); 
  sleep(2000); 
  console.log('data returned from requesting page'); 
} 
function fetchApi(){ 
  console.log('fetching api'); 
  sleep(2000); 
  console.log('data returned from the api'); 
} 
fetchPage(); 
fetchApi(); 

 
当脚本运行时,fetchPage()函数会被调用,直到它返回之前,脚本的运行是被阻塞的,在fetchPage()函数返回之前,程序是不能移到fetchApi()函数中的。这称为阻塞操作。
Node.js几乎从不使用这种编码风格,而是异步地调用回调。
看下下面编码,,

Js代码 

var http = require('http'); 
 
function fetchPage(){ 
  console.log('fetching page'); 
  http.get({host:'www.baidu.com',path:'/&#63;delay=2000'}, 
    function(res){ 
      console.log('data returned from requesting page'); 
    }).on('error',function(e){ 
      console.log("There was an error" + e); 
    }); 
} 
function fetchApi(){ 
  console.log('fetching api'); 
  http.get({host:'www.baidu.com',path:'/&#63;delay=2000'}, 
    function(res){ 
      console.log('data returned from requesting api'); 
    }).on('error',function(e){ 
      console.log("There was an error" + e); 
    }); 
} 
fetchPage(); 
fetchApi(); 

 允许这段代码的时候,就不再等待fetchPage()函数返回了,fetchApi()函数随之立刻被调用。代码通过使用回调,是非阻塞的了。一旦调用了,两个函数都会侦听远程服务器的返回,并以此触发回调函数。
注意这些函数的返回顺序是无法保证的,而是和网络有关。
 
事件循环

Node.js使用javascript的事件循环来支持它所推崇的异步编程风格。基本上,事件循环使得系统可以将回调函数先保存起来,而后当事件在将来发生时再运行。这可以是数据库返回数据,也可以是HTTP请求返回数据。因为回调函数的执行被推迟到事件反生之后,于是就无需停止执行,控制流可以返回到Node运行时的环境,从而让其他事情发生。

Node.js经常被当作是一个网络编程框架,因为它的设计旨在处理网络中数据流的不确定性。促成这样的设计的是事件循环和对回调的使用,他们似的程序员可以编写对网络或I/O事件进行响应的异步代码。

需要遵循的规则有:函数必须快速返回,函数不得阻塞,长时间运行的操作必须移到另一个进程中。
Node.js所不适合的地方包括处理大量数据或者长时间运行计算等。Node.js旨在网络中推送数据并瞬间完成。

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