Node.js 24小时速战


callback

Node.js 使用回调

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);
});

同步和异步

同步和阻塞时可以互用的两个概念,指的是代码(脚本)的执行会在函数返回之前停止,如下面的代码,在 fetchPage() 运行时,它阻塞了整个脚本的运行。其他接下来的操作必须等待。

// blocking code
function sleep(milliseconds) {
  var start = new Date().getTime();
  while((new Date().getTime() - start) < milliseconds) {
    // 超过给定时间才从该循环跳出,模拟了 setTimeout
  }
}

function fetchPage() {
  console.log('fetching page');
  sleep(2000);
  console.log('page fetched');
}

function fetchApi() {
  console.log('fetching api');
  sleep(2000);
  console.log('api fetched');
}

fetchPage();
fetchApi();

异步和非阻塞是可以互用的概念,指的是基于回调的、允许脚本并行(并发)执行操作的方法。脚本无需等待某个操作的结果,因为操作结果会在事件发生时由回调函数来处理。

// non-blocking code
var http = require('http');
function fetchPage() {
  console.log('fetching page');
  http.get({host: 'baidu.com', path: '/?delay=2000'}, function(res) {
    console.log('page fetched');
  }).on('error', function(e) {
    console.log('error occured'+e);
  });
}
function fetchApi() {
  console.log('fetching api');
  http.get({hots: 'baidu.com', path: '/?delay=2000'}, function(res) {
    console.log('api fetched');
  }).on('error', function(e) {
    console.log('error occured'+e);
  });
}

fetchPage();
fetchApi();

事件循环

该机制是确保 Node.js 可以使用回调进行工作的基石。事件循环使得系统可以将回调函数先保存起来,而后当事件发生时再运行。而事件可以是数据库返回数据,也可以是http请求返回数据等。控制流在事件发生后需要执行回调时会回到需要的位置上。
使用基于事件循环进行编程,实际上关键思想是,将代码围绕着事件来构架而不是按照期待中的输入顺序来构架

由于Js中的事件循环以单一进程为基础,所以为了确保高性能,需要遵循以下规则:

  • 函数必须快速返回
  • 函数不得阻塞
  • 长时间运行的操作必须移到另一个进程中

由于以上的第三点,如果程序或函数需要长时间运行才能完成处理,那么事件循环就不是个好选择。Node.js 所不适合的地方包括处理大量数据或者长时间运行计算等。Node.js 旨在在网络中推送数据并瞬间完成

左银右煌 /
Published under (CC) BY-NC-SA in categories programming  tagged with JavaScript  Node.js