JavaScript 为客户端而生,Node.js 为网络而生。Node.js 能做的远不止开发一个网 站那么简单,使用 Node.js,你做以下开发:
- 具有复杂逻辑的网站;
- 基于社交网络的大规模 Web 应用;
- Web Socket 服务器;
- TCP/UDP 套接字应用程序;
- 命令行工具;
- 交互式终端程序;
- 带有图形用户界面的本地应用程序;
- 单元测试工具;
- 客户端 JavaScript 编译器。
此外,nodejs还内置了一个HTTP服务器,也即是换锁不要额外的apache来运行。这个服务器不仅可以用来调试代码,而且它本身就可以部署到产品环境,它的性能足以满足要求。值得一提的是node.js还可以调用c/c++的代码。
直接上官网下载安装就是了,winodws和POSIX系统都支持。
1.进入源码目录
2.执行./configure
3.执行 make
4.sudo make install
大功告成。
使用任意的文本编辑器新建一个helloworld.js文件,写入如下的代码:
console.log('Hello World');
终端切换到该js文件所在的目录,运行命令:node HelloWorld.js(不要求一定是.js) 即可打印出Hello World。
输入node –help
Usage: node [options] [ -e script | script.js ] [arguments]
node debug script.js [arguments]
Options:
-v, --version print Node.js version
-e, --eval script evaluate script
-p, --print evaluate script and print result
-c, --check syntax check script without executing
-i, --interactive always enter the REPL even if stdin
does not appear to be a terminal
-r, --require module to preload (option can be repeated)
--no-deprecation silence deprecation warnings
--trace-deprecation show stack traces on deprecations
--throw-deprecation throw an exception anytime a deprecated function is used
--no-warnings silence all process warnings
--trace-warnings show stack traces on process warnings
--trace-sync-io show stack trace when use of sync IO
is detected after the first tick
--track-heap-objects track heap object allocations for heap snapshots
--prof-process process v8 profiler output generated
using --prof
--zero-fill-buffers automatically zero-fill all newly allocated
Buffer and SlowBuffer instances
--v8-options print v8 command line options
--v8-pool-size=num set v8's thread pool size
--tls-cipher-list=val use an alternative default TLS cipher list
--use-bundled-ca use bundled CA store (default)
--use-openssl-ca use OpenSSL's default CA store
--openssl-config=path load OpenSSL configuration file from the
specified file (overrides OPENSSL_CONF)
--icu-data-dir=dir set ICU data load path to dir
(overrides NODE_ICU_DATA)
--preserve-symlinks preserve symbolic links when resolving
and caching modules.
Environment variables:
NODE_PATH ':'-separated list of directories
prefixed to the module search path.
NODE_DISABLE_COLORS set to 1 to disable colors in the REPL
NODE_ICU_DATA data path for ICU (Intl object) data
NODE_NO_WARNINGS set to 1 to silence process warnings
NODE_PATH ':'-separated list of directories
prefixed to the module search path
NODE_REPL_HISTORY path to the persistent REPL history file
OPENSSL_CONF load OpenSSL configuration from file
Documentation can be found at https://nodejs.org/
以上就是node命令的一些说明,例如-v就是查看版本等。可以看到node.jst提供了另一种输出hello world的方式:在终端运行:node -e “console.log(‘Hello World’);” 也可以说输出Hello World
运行无参数node将会启动一个JavaScript式交互shell
> console.log("Hello world");
Hello world
输入玩你想执行的命令之后按下回车键,Node.js会自动解析并执行命令。
前面提到过node内置了一个http服务器,那么我们该怎样启用呢?
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('Node.js
');
res.write('Node.js');
res.end('Hello World
');
}).listen(3000);
console.log("HTTP server is listening at port 3000.");
然后使用node命令运行就可以使用localhost:3000代开一个页面了。值得注意的是运行之后并不会自动停止,需要按ctrl+c手动停止(有一个坑就是我的macbook输入法没对的时候按ctrl+c是没有反应的)
Running node-supervisor with
program 'HttpServer.js'
--watch '.'
--extensions 'node,js'
--exec 'node'
Starting child process with 'node HttpServer.js'
Watching directory '/Users/xiongyu/Documents/Study/Nodejs' for changes.
Press rs for restarting the process.
HTTP server is listening at port 3000.
crashing child
Starting child process with 'node HttpServer.js'
HTTP server is listening at port 3000.
可以看到supervisor检测到了文件内容发生了变化并重新启动了程序
异步式 I/O(AsynchronousI/O)或非阻塞式I/O(Non-blocking I/O)则针对所有I/O 操作不采用阻塞的策略。当线程遇到I/O操作时,不会以阻塞的方式等待I/O操作 的完成或数据的返回,而只是将I/O 请求发送给操作系统,继续执行下一条语句。当操作系统完成 I/O 操作时,以事件的形式通知执行I/O操作的线程,线程会在特定时候处理这个事件。为了处理异步I/O,线程必须有事件循环,不断地检查有没有未处理的事件,依次予以处理。多线程可以让 CPU 资源不被阻塞中的线程浪费。而在非阻塞模式 下,线程不会被 I/O 阻塞,永远在利用 CPU。多线程带来的好处仅仅是在多核 CPU 的情况 下利用更多的核,而Node.js的单线程也能带来同样的好处。
看一个读取文件的例子:
var fs=require('fs');
fs.readFile('taylor.txt','utf-8',function (err, data) {
if (err) { console.error(err);
} else { console.log(data);
}
});
console.log('Read File:');
taylor.txt是同级目录下的一个文本文件。运行之后可以看到最先打印出的是:Read File:这一句话,这是因为fs.readFile 调用时所做的工作只是将异步式 I/O 请求发送给了操作系统,然后立即 返回并执行后面的语句,执行完以后进入事件循环监听事件。当 fs 接收到 I/O 请求完成的 事件时,事件循环会主动调用回调函数以完成后续工作。因此我们会先看到 Read File:,再看到 taylor.txt 文件的内容。
把上一个例子改一下来说一下时间
var fs = require('fs');
var EventEmitter = require('events').EventEmitter;
var event = new EventEmitter;
fs.readFile('taylor.txt', 'utf-8', function (err, data) {
if (err) {
console.error(err);
} else {
console.log(data);
event.emit("readFinsh");
}
});
event.on("readFinsh", function () {
console.log("文件读完了");
})
console.log('Read File:');
event对象注册了一个事件readFinsh的监听器,当这个事件执行完之后会像event对象发送事件readFinsh,此时会调用readFinsh的监听器。
Node.js 始终在事件循环中,程序入口就是 事件循环第一个事件的回调函数
模块是 Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个 Node.js 文件就是一个模块,这个文件可能是 JavaScript 代码、JSON 或者编译过的 C/C++ 扩展
Node.js 提供了 exports 和 require 两个对 象,其中 exports 是模块公开的接口,require 用于从外部获取一个模块的接口,即所获 取模块的 exports 对象。
模块的代码:
//ReadFile.js
var fs = require('fs');
var EventEmitter = require('events').EventEmitter;
var event = new EventEmitter;
exports.ReadFile = function (fileName) {
fs.readFile(fileName, 'utf-8', function (err, data) {
if (err) {
console.error(err);
} else {
console.log(data);
event.emit("readFinsh");
}
});
}
event.on("readFinsh", function () {
console.log("文件读完了");
})
console.log('Read File:');
引用模块:
//getmodule.js
var mModule=require('./ReadFile');
mModule.ReadFile("taylor.txt")
运行getmodule.js就会引入读出文件内容并打印。上面这个例子有点类似于创建一个对象,但实际上和对象又有本质的区别,因为 require 不会重复加载模块,也就是说无论调用多少次 require,获得的模块都是同一个。
Node.js 的包类似于 C/C++ 的函数库或者 Java/.Net 的类库。Node.js 的包是一个目录,其中包含一个 JSON 格式的包说明文件 package.json。严格符 合 CommonJS 规范的包应该具备以下特征:
Node.js包管理器,即npm是 Node.js 官方提供的包管理工具,它已经成了Node.js 包的 标准发布平台,用于 Node.js 包的发布、传播、依赖控制。npm 提供了命令行工具,使你可 以方便地下载、安装、升级、删除包,也可以让你作为开发者发布并维护包。