前置概念
CPU密集
進(jìn)行的一些壓縮,解壓,加密,解密等計(jì)算都屬于CPU密集
I/O密集
文件的讀取,網(wǎng)絡(luò)操作,數(shù)據(jù)庫(kù)等操作時(shí),為I/O密集
高并發(fā)
單位時(shí)間內(nèi)的訪問(wèn)量
進(jìn)程
是計(jì)算機(jī)中的程序關(guān)于某數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位
NodeJS工作模型
此時(shí),NodeJS可以處理很多用戶發(fā)來(lái)的一些請(qǐng)求,而這寫請(qǐng)求不會(huì)因?yàn)檎{(diào)用I/O操作而空閑,也就是非阻塞I/O,CPU可以不停的進(jìn)行接收請(qǐng)求,并進(jìn)行I/O操作,而I/O操作則是多線程的,當(dāng)I/O操作完成后,CPU再講數(shù)據(jù)返回給客戶端.NodeJS解決了CPU上的空閑和處理高并發(fā)的能力
線程
進(jìn)程內(nèi)一個(gè)相對(duì)獨(dú)立的,可調(diào)度的執(zhí)行單元,與同屬一個(gè)進(jìn)程的線程共享進(jìn)程的資源
多線程
啟動(dòng)一個(gè)進(jìn)程,在一個(gè)進(jìn)程內(nèi)啟動(dòng)多個(gè)線程,這樣,多個(gè)線程也可以一塊執(zhí)行多個(gè)任務(wù)
NodeJS單線程
單線程只是針對(duì)主進(jìn)程,I/O操作系統(tǒng)底層多線程調(diào)度. 單線程并不是單進(jìn)程
環(huán)境
CommonJS
每個(gè)文件是一個(gè)模塊,有自己的作用域
在模塊內(nèi)部module變量代表模塊本身
module.exports屬性代表模塊對(duì)外接口
require 規(guī)則
- / 表示絕對(duì)路徑,./表示相對(duì)于當(dāng)前文件的路徑
- 支持js,json,node擴(kuò)展名,不寫一次嘗試
- 不寫路徑則認(rèn)為是build-in模塊或者各級(jí)node_modules內(nèi)的第三方模塊
require 特性
- module被加載的時(shí)候執(zhí)行,加載后緩存
- 一旦出現(xiàn)某個(gè)模塊被循環(huán)加載,就只輸出已經(jīng)執(zhí)行的部分,還未執(zhí)行的部分不會(huì)輸出
module.exports與exports的區(qū)別
const exports = module.exports // exports就是module.exports的簡(jiǎn)寫
(
function(exports, require, module, __filename, __dirname) {
// code
}
)
exports.test = 100
exports = {
a: 1,
b: 2
}
如果寫成exports,那么exports的指向就會(huì)被改變,它不再指向module.exports,也就什么都沒(méi)有輸出
因此:
module.exports = {
a: 1,
b: 2
}
此時(shí),module.exports將指向了這個(gè)對(duì)象,即輸出了這個(gè)對(duì)象
模塊對(duì)外的輸出永遠(yuǎn)是module.exports,你可以添加它的屬性,但是你不能修改它的指向,如果exports的指向被修改,那么它將不會(huì)對(duì)外輸出
global
- CommonJS
- Buffer,process,console
- timer
// mod1
global.test = 100
// mod2
console.log(test) // 100
process
const {argv, argv0, execArgv, execPath} = process
// argv 啟動(dòng)這個(gè)process的時(shí)候的所有參數(shù)
// argv0 保存了argv這個(gè)數(shù)組的引用
// execArgv 調(diào)用node所調(diào)用的特殊參數(shù)
// execPath argv的第一個(gè)參數(shù)
argv.forEach(item => {
console.log(item)
})
const {env} = process
console.log(env) // 執(zhí)行環(huán)境
console.log(process.cwd()) // 當(dāng)前命令所執(zhí)行的路徑
setImmediate(() => {
console.log('setImmediate')
})
setTimeout(() => {
console.log('setTimeout')
}, 0);
process.nextTick(() => {
console.log('nextTick')
})
nextTick是將其放在了當(dāng)前隊(duì)列的隊(duì)尾,而setImmediate是放在了下一個(gè)隊(duì)列的隊(duì)尾,setTimeout是放在兩者之間
基礎(chǔ)API
normalaize
處理路徑
const {normalize} = require('path')
console.log(normalize('/usr//local/bin'))
join
拼接路徑
const {join} = require('path')
console.log(join('/usr', 'local', 'bin/'))
resolve
相對(duì)路徑解析為絕對(duì)路徑
const {resolve} = require('path')
console.log(resolve('./'))
basename dirname extname
const {basename, dirname, extname} = require('path')
const filePath = '/usr/local/bin/no.txt'
console.log(basename(filePath)) // 文件名
console.log(dirname(filePath)) // 路徑
console.log(extname(filePath)) // 擴(kuò)展名
parse format
分析路徑
const {parse, format} = require('path')
const filePath = '/usr/local/include'
const ret = parse(filePath)
console.log(ret)
console.log(format(ret)) // 將拆分的路徑執(zhí)行回來(lái)
輸出
{ root: '/',
dir: '/usr/local',
base: 'include',
ext: '',
name: 'include' }
sep delimiter win32 posix
和操作系統(tǒng)相關(guān)的一些東西
const {sep, delimiter, win32, posix} = require('path')
console.log('sep:', sep) // 路徑分隔符 /
console.log('win sep', win32.sep) // \
console.log('PATH:', process.env.PATH)
// PATH: /Library/Frameworks/Python.framework/Versions/3.6/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin
console.log('delimiter:', delimiter) // :
console.log('win delimiter:', delimiter) // :
總結(jié)
__dirname,__filename 總是返回文件的絕對(duì)路徑
process.cwd()總是返回執(zhí)行node命令所在文件夾
Buffer
處理二進(jìn)制數(shù)據(jù)流 實(shí)例類似整數(shù)數(shù)組,大小固定
console.log(Buffer.alloc(10))
console.log(Buffer.alloc(5, 1))
console.log(Buffer.allocUnsafe(5,1))
console.log(Buffer.from([1,2,3]))
console.log(Buffer.from('test'))
<Buffer 00 00 00 00 00 00 00 00 00 00>
<Buffer 01 01 01 01 01>
<Buffer 18 e3 04 04 01>
<Buffer 01 02 03>
<Buffer 74 65 73 74>
console.log(Buffer.byteLength('test')) // 字節(jié)長(zhǎng)度
console.log(Buffer.byteLength('測(cè)試'))
console.log(Buffer.isBuffer({})) // false
console.log(Buffer.isBuffer(Buffer.from([1, 2, 3]))) // true
const buf1 = Buffer.from('h')
const buf2 = Buffer.from('e')
const buf3 = Buffer.from('l')
const buf4 = Buffer.from('l')
const buf5 = Buffer.from('o')
const buf = Buffer.concat([buf1, buf2, buf3, buf4, buf5])
console.log(buf) // 連接buffer
const buf = Buffer.from('this is a test')
/* buf.length
buf.toString()
buf.fill() // 填充
buf.equals()
buf.indexOf()
buf.copy() */
events
const EventEmitter = require('events')
class CustomEvent extends EventEmitter {
}
const ce = new CustomEvent()
ce.on('test', () => {
console.log('this is a test')
})
setInterval(() => {
ce.emit('test')
}, 500)
const EventEmitter = require('events')
class CustomEvent extends EventEmitter{}
const ce = new CustomEvent()
ce.on('error', err => {
console.log(err)
})
ce.emit('error', new Error('oops'))
執(zhí)行一次
import { setInterval } from 'timers';
const EventEmitter = require('events')
class CustomEvent extends EventEmitter{}
const ce = new CustomEvent()
ce.once('test', () => {
console.log('test event')
})
setInterval(() => {
ce.emit('test')
}, 500)
移除
const EventEmitter = require('events')
class CustomEvent extends EventEmitter{}
const ce = new CustomEvent()
function fn1() {
console.log('fn1')
}
ce.on('test', fn1)
ce.on('test', fn2)
setInterval(() => {
ce.emit('test')
}, 500)
setTimeout(() => {
ce.removeListener('test', fn2)
}, 1500);
fs
讀文件
const fs = require('fs')
fs.readFile('./module2.js','utf8', (err, data) => {
if (err) throw err
console.log(data)
})
同步操作
const data = fs.readFileSync('./module1.js', 'utf8')
console.log(data)
寫文件
const fs = require('fs')
fs.writeFile('./text', 'this is a test', {
encoding: 'utf8'
}, err => {
if(err) throw err
console.log('done')
})
查看文件狀態(tài)
const fs = require('fs')
fs.stat('./fs.js', (err, stats) => {
if(err) throw err
console.log(stats.isFile())
console.log(stats.isDirectory())
console.log(stats)
})
重命名
const fs = require('fs')
fs.rename('./text', 'text.txt', err => {
if (err) throw err
})
打印目錄的文件名
const fs = require('fs')
fs.readdir('../', (err, files) => {
if (err) throw err
console.log(files)
})
刪除文件夾
const fs = require('fs')
fs.rmdir('./text', err => {
if(err) throw err
})
監(jiān)視文件或目錄的變化