各个平台都有相关的包管理工具,Ubuntu
下的apt-get
,CentOS
下的yum
,macOS
下的homebrew
,便于安装和卸载软件。Node.js是名副其实的版本帝,版本更新之快使得上述的工具不适用,开发机器有可能须要同时存在几个Node.js的大版本,每一个Node.js内置的npm又有版本的差别,并且,国内网络访问npmjs.org镜像速度很慢,因此,推荐适用3m安装法。前端
nvm
是一个开源的Node.js版本管理器,经过简单的bash脚原本管理、切换多个Node.js版本。node
注意:nvm不支持windows版本,但有替代品nvm-windowsreact
安装:jquery
# nvm 安装
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.0/install.sh | bash
# node.js 安装 官网最新LTS
nvm install 12.13.1
复制代码
查看环境配置:webpack
cat ~/.bash_profile
复制代码
执行source
命令,是环境生效git
source ~/.bash_profile
复制代码
注意:也可根据当前终端shell类型查看不一样配置。若是是zsh,查看.zshrc,若是是bash,查看.bashrcangularjs
查看可安装版本:github
nvm ls-remote
复制代码
本机已安装版本:web
nvm ls
复制代码
版本类型:shell
tip: 通常奇数版本都是尝试性的,通常LTS版本都是偶数
使用 nvm
安装 Node.js 8.x
nvm install 8
复制代码
指定默认版本:
nvm alias default 11
复制代码
切换版本:
nvm use 12
复制代码
npm
一般称为node包管理器。它的主要功能就是管理Node.js的包,包括:安装、卸载、更新、查看、搜索、发布等。它最开始的初衷是只是Node.js包管理器,随着前端技术react、webpack、browserify等发展,目前npm的定位是广义的包管理器,包括js、react、mobile、angularjs、browsers、jquery、cordova、bower、gulp、grunt、browserify、docpad、nodebots、tessel等,是开源世界里最大、生态最健全的包管理器。
Node.js集成了npm
,因此安装Node.js时也一并安装了。也可使用npm
命令来更新安装。
[sudo] npm install npm -g
#指定版本
[sudo]npm install -g npm@2.9
复制代码
使用场景有:
使用npm
安装模块:略
Node.js和其余语言同样,默认将模块托管在 npmjs.org
,这是官方的registry(源),registry是指从哪一个源下载Node.js模块,固然其余组织或我的也是能够自建npm registry
(源)的,这些非官方的镜像会按期的和npm官方registry(源)进行同步,通常在10分钟左右一次。
npm提供的配置源:
npm config set registry <registry url>
复制代码
这个处理的问题在于切换源的时候比较麻烦。nrm
就是专门用于解决这个问题,它能够帮助你简单、快速的在不一样的npm registry(源)之间进行切换,它默认内置了不少经常使用的源,包括npm、cnpm、taobao、 nj、rednpm、npmMirror,固然你能够本身经过nrm add维护本身的源。
安装 nrm
:
npm install -g nrm
复制代码
测速:
➜ ~ nrm test
npm ---- 732ms
yarn --- 745ms
* cnpm --- 180ms
taobao - 226ms
nj ----- Fetch Error
npmMirror 4493ms
edunpm - Fetch Error
复制代码
查看源:
➜ ~ nrm ls
npm -------- https://registry.npmjs.org/
yarn ------- https://registry.yarnpkg.com/
* cnpm ------- http://r.cnpmjs.org/
taobao ----- https://registry.npm.taobao.org/
nj --------- https://registry.nodejitsu.com/
npmMirror -- https://skimdb.npmjs.com/registry/
edunpm ----- http://registry.enpmjs.org/
复制代码
切换源: 不须要记住 registry 的具体URL,使用registry的名字
nrm use <registry name>
➜ ~ nrm use taobao
Registry has been set to: https://registry.npm.taobao.org/
复制代码
增长源:
nrm add <regsitry url>
复制代码
目的:
浏览器中的异步核心技术是Ajax,异步Javascript和XML。Node.js的异步原理的核心是EventLoop。
看图说话:
Ajax 异步处理:
Node.js 异步处理:
调用Node.js API的方法的时候,它会把具体操做和回调函数交给 EventLoop 去执行,EventLoop 维护了一个任务队列(microTask),等异步操做执行完成,队列中的回调函数会按照先进先出(FIFO)的顺序执行。
🌰 获取目录下的全部文件的API
# hello-async.js
const fs = require('fs')
const path = '.'
fs.readdir(path, function(err, files) {
if (err) {
console.log(err)
return;
}
console.log(files)
})
复制代码
# hello-sync.js
const fs = require('fs')
console.log(fs.readdirSync('.'))
复制代码
注意:高并发场景下慎用同步写法,否则可能会成为性能瓶颈,跟Node.js的设计初衷是相悖的。
Node.js 中有两种事件处理方式,callback
和 EventEmitter
。 callback
采用错误优先的回调方式,后者是事件驱动力里的事件发射器。
Node.js 极其依赖异步代码和回调来保证执行效率。Node.js SDK 中的 callback 使用 错误优先回调(error-first-callback)写法。规则以下:
error
对象,若是发生错误,该对象会做为第一个参数返回,正常返回null。🌰见 hello-err-first.js
这个🌰告诉咱们:
try-catch
简单理解为“发布/订阅”模式,和前端的事件机制相似,如Vue里面的 $emit
和 $on
。
const EventEmitter = require('events')
const obsever = new EventEmitter()
obsever.on('topic', function() {
console.log('topic has occured')
})
function main() {
console.log('start')
obsever.emit('topic')
console.log('end')
}
main()
复制代码
**注意:对于EventEmitter 的 on
来讲,Node.js容许同一个事件最多指定10个回调函数,超过会发出警告。能够经过设置setMaxListeners
方法改变。 **
Node.js采用了错误优先的回调写法,致使SDK中导出的都是回调函数,若是组合调用这些函数,常常会出现回调里嵌套回调的问题。这种写法称之为回调地狱。
🌰
step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
// Do something with value4
});
});
});
});
复制代码
Node.js如何解决回调地狱:
Promise
🌰 1
const fs = require('fs')
function hello(file) {
return new Promise(function(resolve, reject ) {
fs.readFile(file, function(err, data) {
if (err) {
reject(err)
} else {
resolve(data.toString())
}
})
})
}
hello('./hello-events.js')
.then(function(res) {
console.log(res)
})
.catch(function(err) {
console.log(err)
})
复制代码
使用Promise 实例处理异步流程控制,约定了每一个函数的返回值都是 Promise 对象,所以均可以使用 then
方法处理。
使用reject
和 resolve
重塑流程:
const fs = require('fs')
function hello(file) {
return new Promise(function(resolve, reject ) {
fs.readFile(file, function(err, data) {
if (err) {
reject(err)
} else {
resolve(data.toString())
}
})
})
}
hello('../main.js')
.then (function(data) {
return new Promise(function(resolve, reject) {
console.log('promise1\n', data)
resolve(data)
})
})
.then(function(data) {
return new Promise(function(resolve, reject) {
console.log('promise2\n', data)
resolve(1)
})
})
.then(function(data) {
return new Promise(function(resolve, reject) {
console.log('promise3\n', data)
reject(new Error('reject'))
})
})
.catch(function(err) {
console.log('catch\n', err)
})
复制代码
const fs = require('fs')
function hello(file) {
return new Promise(function(resolve, reject ) {
fs.readFile(file, function(err, data) {
if (err) {
reject(err)
} else {
resolve(data.toString())
}
})
})
}
hello('./main.js')
.then (function(data) {
return new Promise(function(resolve, reject) {
console.log('promise1\n', data)
resolve(data)
})
.then(function(res) {
return new Promise(function(resolve, reject) {
console.log('promise2\n', data)
resolve(1)
})
})
.catch(function(err) {
console.log('catch', err)
})
})
.catch(function(err) {
console.log('catch\n', err)
})
复制代码
const fs = require('fs')
function hello(file) {
return new Promise(function(resolve, reject ) {
fs.readFile(file, function(err, data) {
if (err) {
reject(err)
} else {
resolve(data.toString())
}
})
})
}
const step1 = function(data) {
return new Promise(function(resolve, reject) {
console.log('promise1\n', data)
resolve(data)
})
.then(function(res) {
return new Promise(function(resolve, reject) {
console.log('promise2\n', data)
resolve(1)
})
})
.catch(function(err) {
console.log('catch', err)
})
}
const step2 = function(data) {
return new Promise(function(resolve, reject) {
console.log('promise3\n', data)
reject(new Error('reject'))
})
}
hello('./hello-sync.js')
.then(step1)
.then(step2)
.catch(function(err) {
console.log(err)
})
复制代码
# hello-reflow-module.js
const hello = require('./tasks/hello')
const step1 = require('./tasks/step1')
const step2 = require('./tasks/step2')
hello('../hello-json.json')
.then(step1)
.then(step2)
.catch(function(err) {
console.log(err)
})
复制代码
书籍:《狼书(卷1):更了不得的Node.js》
社区:cnodejs