node.js 同步和异步

Node.js运行在单一进程并实现了异步编码的风格,异步编码风格并不是node.js或javascript的特有的而是一种编程风格。

同步的代码意味着每次只执行一个操作,在一个操作完成之前代码的执行会被阻塞,无法移到下一个操作上。

异步的代码基于回调、允许脚本并行执行操作。脚本不用等待某个操作的结果而可以继续前行,因为操作结果会在事件发生由回调来处理。

什么是回调呢?回调是将一个函数作为参数传给另一个函数,并在通常第一函数完成被调用。

node.js实际上是基于事件回调、事件循环来实现了异步编程。使得程序员可以编写对网络或者IO事件进行相应的异步代码。

下面通过两组代码来体验同步和异步的差别:

同步:

function sleep(milliseconds) {
  var start = new Date().getTime();
  while ((new Date().getTime() - start) < milliseconds){
  }
}


function fetchPage() {
  console.log('fetching page');
  sleep(2000); // simulate time to query a database
  console.log('data returned from requesting page');
}


function fetchApi() {
  console.log('fetching api');
  sleep(2000); // simulate time to fetch from an api
  console.log('data returned from the api');
}


fetchPage();
fetchApi();

执行结果:

fetching page
data returned from requesting page
fetching api
data returned from the api


异步:

var http = require('http');


function fetchPage() {
  console.log('fetching page');
  http.get({ host: 'trafficjamapp.herokuapp.com', path: '/?delay=2000' }, function() {
    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: 'trafficjamapp.herokuapp.com', path: '/?delay=2000' }, function() {
    console.log('data returned from the api');
  }).on('error', function(e) {
    console.log("There was an error" + e);
  });
}


fetchPage();
fetchApi();


执行结果:

fetching page
fetching api
data returned from requesting page
data returned from the api


同步代码在执行时,fetchPage()会被调用直到他返回之前脚本的执行是被阻塞的。程序是不能移到fetchApi()的函数中。这称为阻塞操作。异步代码在执行fetchPage()时就不需要等待函数返回,fetchApi()函数随之执行。通过使用了回调,是非阻塞的,两个函数都会监听远程服务的返回,并以此触发回调函数。

另外,同步,异步,阻塞,非阻塞这四个术语中,阻塞和同步几乎可以互换使用,指代码的执行会在函数返回之前停止,如果是阻塞,某个操作阻塞,脚本无法继续执行,对于最终用户,就意味着等待。异步和非阻塞亦可以互换使用,值得是基于回调、允许脚本并行执行操作的,脚本无需等待某个操作结果才能继续执行,操作结果会在事件发生时由回调处理。

你可能感兴趣的:(Node.js)