一个Node.js初学者的“班门弄斧

凌晨三点,当启动控制台(console)的时候,手已经按在键盘上了。黑色背景上出现了扎眼的提示,渴求接收命令。想折腾下node.js?node,js有一个使人兴奋的消息:它能够在任何地方运行。这一点让栈有了多种不一样的尝试方式。对任何一个经验丰富的人,使用命令行来运行都充满了乐趣。我最喜欢的是能够在命令行的安全网络中审阅栈。牛逼的是咱们仍然在说javascript,因此大家中的大部分不会有任何问题。那么,为何不开始在console里启动node呢?javascript

本文中,我会向你介绍Node.js。个人目标是在一些有难度的地方能看下出彩的部分。本文是一篇概述留存在console里的栈的媒介。若是你想看看适合新手的Node.js指南,不妨看看SitePoint的优质课程Node.js:An Introduction.html

为何是Node.js?

在咱们开始前,先看看让Node.js鹤立鸡群的”花边“新闻:java

  • 为非阻塞I/O而设计
  • 为异步操做而设计
  • 驱动Chrome的V8 JavaScript

你可能已经从不少地方知道以上几点了,可是这些究竟是什么意思呢?你能够将Node.js看做是一个为javascript提供了大量API的引擎。在传统的同步编程方式中,当你有一个I/O操做时,API在运行下一条指令前会处于等待状态。I/O操做就是,举个例子,读取文件或发出一个网络请求。Node.js不一样,它从设计之初就是为了异步操做。在当下的编程环境,这一点有巨大的优点。你还能想起你最后一次由于一个更快的单核处理器而换电脑是何时吗?处理器的数量和更快的硬盘更加剧要。node

接下来的文章中,当你看到>这个提示标志时,意味着须要按enter并输入下一条指令。此外,在运行本文中的代码时,你须要开启CLI,并执行指令node(注:须要先下载并安装node.js),说着就开始吧!web

回调(Callbacks)

首先输入下列函数:编程

  1. >function add(a,b,callback){var result = a+b;callback(result);}
 

 对网络新手,JavaScript中的callback可能很陌生。这看起来并非一个典型的OOP方法。在JavaScript中,函数(function)是一个对象,对象能够接受其它对象做为参数。JavaScript并不在意对象是什么,因此一个函数能够接受另外一个是函数的对象。数字参数数量,在回调函数中经过add()由两个变为一个。回调系统至关的强大,由于它支持封装并将现实封装隐藏。在Node.js中,你会发现有许多APIs将一个回调做为参数。能够把回调想象成是一个表明。程序隐藏在里面,而这个表明就是经受权被派遣代替别人的人。因此回调像是派一我的来完成差事。给一系列参数,就像列出一个购物单,而后他们就本身去完成任务了。api

为了玩转add():浏览器

  1. > add(2, 3, function (c) { console.log('2 + 3 = ' + c) });
  2. > add(1, 1, function (c) { console.log('Is 1 + 1 = 3? ' + (c === 3)); });
 

 多尝试一些回调的新奇玩法吧。它是Node.js中一些重要API的基础。安全

异步操做

经过回调,咱们能够开始编写一些异步API了,举个栗子(其实这个季节彷佛没有栗子能够举):服务器

  1. > function doSomething (asyncCallback) { asyncCallback(); }
  2. > doSomething(function () { console.log('This runs synchronously.'); });
 

 这个特例中有一个同步操做,可是对于JavaScript中的异步操做,咱们已经万事俱备了。asyncCallback,能够在一些线程中被延迟:

  1. > function doSomething (asyncCallback) { setTimeout(asyncCallback, Math.random() + 1000); }
  2. > doSomething(function () { console.log('This runs asynchronously.'); }); console.log('test');
 

 我用了setTimeout在当前线程中延迟操做。timeout并无给定时间,因此我使用Math.random()来设一个变化的时间。取名为doSomething,而后用console.log(‘test’)来显示被延后的操做。在1~2秒钟后,就能够在屏幕上看懂啊弹出的消息了。我举例的异步回调是不可预测的。Node.js将其放在时间表里,继续前面的进程。时间到了后,Node,js恰好运行到这个异步操做的时间,而后调用这个回调。因此你必须脑中明晰各类回调以更好的理解Node.js。

一句话,在JavaScript中,回调并不老是它看起来的样子。

让咱们作一些更有趣的事(原谅我没发现哪里有趣)。不如试试在Node.js中查找DNS?

  1. > dns.lookup('bing.com', function (err, address, family) { console.log(' Address: ' + address + ', Family: ' + family + ', Err: ' + err); });
 
 

 这个回调返回err,address,family三个对象,重点是返回值被看成参数传递给回调。因此这个传统的像var result= fn('bing.com')不太同样。在Node.js中,必须经过回调和异步来得到整体概况。你能够去看看[DNS Node.js API][2]了解更多细节。下图是我控制台里DNS lookup的样子:

文件I/O

如今继续,在Node,js中怎么执行文件写入写出呢?想象这个场景:你打开一个文件,读取文件内容而后写入新的内容。在现代工艺的电脑上I/O-bound(天,我彻底不知道这怎么翻译,知道的私信我,我改)操做很慢。CPU处理速度很快,RAM也很快。可是,硬盘的读取或写入速度很慢。所以当程序同步执行I/O-bound操做时,运行的很慢。替代方法是采用异步,好比:

  1. > var fs = require('fs');
  2. > fs.writeFile('message.txt', 'Hello Node.js', function () { console.log('Saved.'); }); console.log('Writing file...');
 

 由于操做是异步的,所以你会先看到“writing file...."而后看到文件被保存。回调函数最普通的使用方式十分适合这个API。你能够看看文档[file System API][6]这部分。读取文件又是怎样作呢?你能经过前例猜猜么?给你一点小提示,回调参数是err和data.我建议你试试。

答案:

  1. > fs.readFile('message.txt', function(err, data) { console.log(data); });
 

 你也能够传入一个encoding项来读取文件中utf-8内容:

  1. > fs.readFile('message.txt', {encoding: 'utf-8'}, function(err, data) { console.log(data); });
 

Node.js回调函数的异步I/O操做看起来很完美。

Web 服务器

那么在Web服务器上会怎样呢?任何一个优秀的Exposé(MacOS上的多窗口管理工具?)都必须运行一个Web服务端。假设有一个叫作creatServer的API,这个API有一个参数是request和response的回调。你能够在文档中看看HTTP API。你能想到是什么样子吗?你须要Http模块。去console里试试吧。

 

答案:

  1. > var http = require('http');
  2. > var server = http.createServer(function (request, response) { response.end('Hello Node.js'); });
 

 细想一下web,它是一个带有请求和响应模块的客户端-服务器。Node.js有一个来自客户端的request对象和一个来自服务器的response对象。所以栈经过简单的回调原理解决web难题。还记得它是异步的吗?我但愿你能把零散的回忆综合一下,若是你看了API文档,咱们如今作的很那个差很少。咱们载入一个模块,告诉它要作什么并给它一个参数。回调就会像一个表明那样工做:执行一个有一系列参数的特殊任务。

固然,若是咱们不能在浏览器中看到它,那么一切都是无心义的。在CLI中添加:

  1. server.listen(8080);
 

 而后将你最爱的浏览器指定为:localhost:8080,我用的是Edge。

假设requset对象有一堆可获取的信息。为了从新连上server,先将其关闭(bring it down):

  1. > server.close();
  2. > server = http.createServer(function (request, response) { response.end(request.headers['user-agent']); }); server.listen(8081);
 
 

 将浏览器指定为:localhost:8081.header提供给你来自浏览器的user-agent信息。咱们能够遍历header对象:

  1. > server.close();
  2. > server = http.createServer(function (request, response) { Object.keys(request.headers).forEach(function (key) { response.write(key + ': ' + request.headers[key] + ' '); }); response.end(); }); server.listen(8082);
 
 

此次 将浏览器指定为:localhost:8082。一旦完成以后,记得关闭。不然命令行可能会产生奇怪的运行结果。

  1. > server.close();
 

 你已经学会啦,经过命令行来建立web服务器。我但愿你喜欢这趟node迷幻之旅。

总结

Node.js很适合现代的解决方案,由于其十分简单而轻便。它充分利用了现代硬件非模块设计的优势。它包含了web固有的客户端-服务器模块。最好都用咱们喜欢的JavaScript运行。引发我兴趣的是栈的关键部分并不前沿。网页来自早期构建的轻量级易接入模块。若是有时间,我建议你看看Tim Berners-Lees’ Design Principles.。原则中为Node.js的least power applies提供了JavaScript选项。

原文连接:http://www.gbtags.com/gb/share/9522.htm

相关文章
相关标签/搜索