Node.js

nodejs.png

前置概念

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工作模型

image.png

此時(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)視文件或目錄的變化

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末啸澡,一起剝皮案震驚了整個(gè)濱河市上沐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌两入,老刑警劉巖剃氧,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異恨狈,居然都是意外死亡吗氏,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門兴喂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)酱酬,“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了缀皱?”我有些...
    開(kāi)封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵免钻,是天一觀的道長(zhǎng)拆魏。 經(jīng)常有香客問(wèn)我事镣,道長(zhǎng)喊递,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任殉疼,我火速辦了婚禮礼预,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘摊趾。我一直安慰自己肛炮,他們只是感情好瘩燥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布二拐。 她就那樣靜靜地躺著吟孙,像睡著了一般巷挥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上涝涤,一...
    開(kāi)封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音罪针,去河邊找鬼。 笑死黄伊,一個(gè)胖子當(dāng)著我的面吹牛泪酱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播还最,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼墓阀,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了拓轻?” 一聲冷哼從身側(cè)響起斯撮,我...
    開(kāi)封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎扶叉,沒(méi)想到半個(gè)月后勿锅,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡枣氧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年溢十,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片达吞。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡张弛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酪劫,到底是詐尸還是另有隱情吞鸭,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布覆糟,位于F島的核電站刻剥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏滩字。R本人自食惡果不足惜透敌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望踢械。 院中可真熱鬧酗电,春花似錦、人聲如沸内列。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)话瞧。三九已至嫩与,卻和暖如春寝姿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背划滋。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工饵筑, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人处坪。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓根资,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親同窘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子玄帕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • topics: 1.The Node.js philosophy 2.The reactor pattern 3....
    宮若石閱讀 1,080評(píng)論 0 1
  • V8最大的特點(diǎn)就是單線程,一次只能運(yùn)行一個(gè)任務(wù) node存在大量異步操作 在異步操作中想邦,無(wú)法通過(guò)try...cat...
    阡陌哥哥閱讀 576評(píng)論 0 0
  • 很多Node.js初學(xué)者都會(huì)有這樣的疑惑裤纹,Node.js到底是單線程的還是多線程的?通過(guò)本章的學(xué)習(xí)丧没,能夠讓讀者較為...
    越努力越幸運(yùn)_952c閱讀 3,646評(píng)論 4 36
  • Node.js是目前非常火熱的技術(shù)呕童,但是它的誕生經(jīng)歷卻很奇特吹零。 眾所周知,在Netscape設(shè)計(jì)出JavaScri...
    Myselfyan閱讀 4,072評(píng)論 2 58
  • 無(wú)盡的燈火啊 像一支支利箭刺向我 我在這箭簇的利刃上翻滾 我血肉模糊 我遍體鱗傷 我感覺(jué)到無(wú)盡的痛 痛到流干了血淚...
    十月胡楊閱讀 229評(píng)論 0 5