Node.js学习笔记

来源:互联网 发布:北交大淘宝地址怎么填 编辑:程序博客网 时间:2024/06/04 19:38

Node.js

JavaScript 为客户端而生,Node.js 为网络而生。Node.js 能做的远不止开发一个网 站那么简单,使用 Node.js,你做以下开发:
- 具有复杂逻辑的网站;
- 基于社交网络的大规模 Web 应用;
- Web Socket 服务器;
- TCP/UDP 套接字应用程序;
- 命令行工具;
- 交互式终端程序;
- 带有图形用户界面的本地应用程序;
- 单元测试工具;
- 客户端 JavaScript 编译器。
此外,nodejs还内置了一个HTTP服务器,也即是换锁不要额外的apache来运行。这个服务器不仅可以用来调试代码,而且它本身就可以部署到产品环境,它的性能足以满足要求。值得一提的是node.js还可以调用c/c++的代码。

安装配置Node.js

直接上官网下载安装就是了,winodws和POSIX系统都支持。

源码编译

环境要求

  • c++编译器
  • python
  • libssl-dev 提供 SSL/TLS 加密支持

编译步骤

1.进入源码目录

2.执行./configure

3.执行 make

4.sudo make install

大功告成。

HelloWorld

使用任意的文本编辑器新建一个helloworld.js文件,写入如下的代码:

console.log('Hello World');

终端切换到该js文件所在的目录,运行命令:node HelloWorld.js(不要求一定是.js) 即可打印出Hello World。

Node.js 命令行工具解析

输入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 REPLNODE_ICU_DATA            data path for ICU (Intl object) dataNODE_NO_WARNINGS           set to 1 to silence process warningsNODE_PATH               ':'-separated list of directories                        prefixed to the module search pathNODE_REPL_HISTORY       path to the persistent REPL history fileOPENSSL_CONF            load OpenSSL configuration from fileDocumentation can be found at https://nodejs.org/

以上就是node命令的一些说明,例如-v就是查看版本等。可以看到node.jst提供了另一种输出hello world的方式:在终端运行:node -e “console.log(‘Hello World’);” 也可以说输出Hello World

REPL 模式

运行无参数node将会启动一个JavaScript式交互shell

> console.log("Hello world");Hello world

输入玩你想执行的命令之后按下回车键,Node.js会自动解析并执行命令。

建立http服务器

前面提到过node内置了一个http服务器,那么我们该怎样启用呢?

var http = require('http');http.createServer(function (req, res) {    res.writeHead(200, {'Content-Type': 'text/html'});    res.write('<h1>Node.js</h1>');    res.write('<img src="https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=950502116,2213091146&fm=58&u_exp_0=383468501,1879785736&fm_exp_0=86&bpow=1000&bpoh=1500">Node.js</img>');    res.end('<p>Hello World</p>');}).listen(3000);console.log("HTTP server is listening at port 3000.");

然后使用node命令运行就可以使用localhost:3000代开一个页面了。值得注意的是运行之后并不会自动停止,需要按ctrl+c手动停止(有一个坑就是我的macbook输入法没对的时候按ctrl+c是没有反应的)

tips使用supervisor监视代码并重新自动重启

  • 运行命令sudo npm install -g supervisor安装supervisor
  • 使用supervisor 命令运行
    从执行成功然后到更改代码并保存,终端会输入以下内容:
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 childStarting child process with 'node HttpServer.js'HTTP server is listening at port 3000.

可以看到supervisor检测到了文件内容发生了变化并重新启动了程序

异步式 I/O 与事件式编程

阻塞与线程

异步式 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.jsvar 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.jsvar mModule=require('./ReadFile');mModule.ReadFile("taylor.txt")

运行getmodule.js就会引入读出文件内容并打印。上面这个例子有点类似于创建一个对象,但实际上和对象又有本质的区别,因为 require 不会重复加载模块,也就是说无论调用多少次 require,获得的模块都是同一个。

创建包

Node.js 的包类似于 C/C++ 的函数库或者 Java/.Net 的类库。Node.js 的包是一个目录,其中包含一个 JSON 格式的包说明文件 package.json。严格符 合 CommonJS 规范的包应该具备以下特征:

  • package.json 必须在包的顶层目录下;
  • 二进制文件应该在bin目录下;
  • JavaScript代码应该在lib 目录下;
  • 文档应该在doc目录下;
  • 单元测试应该在test目录下。
    这里有个要注意的就是如果没有package.json的话,node.js会尝试寻找 index.js 或 index.node 作为包的接口。如果都没有,就会报错。也可以使用npm init可以根据交互式问答 产生一个符合标准的 package.json

包管理器

Node.js包管理器,即npm是 Node.js 官方提供的包管理工具,它已经成了Node.js 包的 标准发布平台,用于 Node.js 包的发布、传播、依赖控制。npm 提供了命令行工具,使你可 以方便地下载、安装、升级、删除包,也可以让你作为开发者发布并维护包。

原创粉丝点击