少妇脱了内裤让我添,久久久久亚洲精品无码网址蜜桃,性色av免费观看,久久人妻av无码中文专区

分享

成為自信的node.js開發(fā)者(一)

 風(fēng)聲之家 2021-03-19

x原創(chuàng) 霧豹 前端技術(shù)優(yōu)選 6天前

作者:霧豹

原文地址:https:///post/5c6a780451882561dd7b65d6

適合閱讀的同學(xué)

想更進(jìn)一步深入理解node的同學(xué),如果你已經(jīng)稍微了解一點(diǎn)點(diǎn)node, 可以用node做一些小demo,并且想更深一步的了解,希望這篇文章可以幫助到你。

不太適合閱讀的同學(xué)

  1. 不太熟悉基本的javascript 語法,比如說回調(diào)函數(shù)

  2. 對node有深入理解的同學(xué),比如說,可以清晰的說出event-loop

Node 架構(gòu)——v8、libuv

第一部分,我們先了解一下node的結(jié)構(gòu),對node先有一個(gè)整體上的認(rèn)識。只有這樣,我們才能編寫出更加高性能的代碼,在遇到問題時(shí),也知道解決的思路。

先來看一張圖表:

圖片

最上面是我們編寫的node.js的代碼,當(dāng)我們執(zhí)行node index.js的命令時(shí),我們是觸發(fā)了一個(gè)node的程序,和其他的javascript的項(xiàng)目,比如說前端的h5項(xiàng)目一樣,該node程序需要有其他的依賴,其中最主要的兩個(gè)依賴是 v8 和 libuv。

  1. v8是 google 開源的引擎,目的是在瀏覽器世界外可以運(yùn)行javascript的代碼。

  2. libuv 是c++ 開源的項(xiàng)目,最初就是專門為node設(shè)計(jì),目的是給node和操作系統(tǒng)交互的能力,比如說網(wǎng)絡(luò), 操作文件。

node在可見的未來仍將繼續(xù)使用v8, 但是微軟edge瀏覽器的chakra(讀法:渣坷垃)引擎也是一個(gè)強(qiáng)有力的競爭者。https://github.com/nodejs/node-chakracore 這個(gè)項(xiàng)目是如何讓node如何跑在chakras 引擎上

v8 引擎

我們現(xiàn)在知道了,node 使用 v8 用來執(zhí)行javascript 代碼,這意味著,node中所支持的javascript的特性,是由 v8 引擎所決定的。

V8引擎支持的 javascript 特性被劃分為三個(gè)不同的group: ShippingStagedIn Progress。

默認(rèn)情況下Shipping group的特性可以直接使用,Staged group的特性需要使用--harmony選項(xiàng)來開啟。如下所示:

? node -v
v7.9.0
? node -p 'process.versions.v8'
5.5.372.43
? node -p "'Node'.padEnd(8, '*')" // 默認(rèn)是不支持的
[eval]:1
'Node'.padEnd(8, '*')
^

TypeError: "Node".padEnd is not a function
at [eval]:1:8
at ContextifyScript.Script.runInThisContext (vm.js:23:33)
at Object.runInThisContext (vm.js:95:38)
at Object. ([eval]-wrapper:6:22)
at Module._compile (module.js:571:32)
at evalScript (bootstrap_node.js:387:27)
at run (bootstrap_node.js:120:11)
at run (bootstrap_node.js:423:7)
at startup (bootstrap_node.js:119:9)
at bootstrap_node.js:538:3
? node --harmony -p "'Node'.padEnd(8, '*')" // 通過--harmony
Node****

In Progress group的feature不穩(wěn)定,但你也可以使用特定的flag來開啟,通過 node --v8-options 命令可以查看,通過grep 命令去查找in progress,如下:

? node --v8-options | grep "in progress"
--harmony_array_prototype_values (enable "harmony Array.prototype.values" (in progress))
--harmony_function_sent (enable "harmony function.sent" (in progress))
--harmony_sharedarraybuffer (enable "harmony sharedarraybuffer" (in progress))
--harmony_simd (enable "harmony simd" (in progress))
--harmony_do_expressions (enable "harmony do-expressions" (in progress))
--harmony_restrictive_generators (enable "harmony restrictions on generator declarations" (in progress))
--harmony_regexp_named_captures (enable "harmony regexp named captures" (in progress))
--harmony_regexp_property (enable "harmony unicode regexp property classes" (in progress))
--harmony_for_in (enable "harmony for-in syntax" (in progress))
--harmony_trailing_commas (enable "harmony trailing commas in function parameter lists" (in progress))
--harmony_class_fields (enable "harmony public fields in class literals" (in progress))

比如說,上面打印出來的倒數(shù)第二行-- harmony_trailing_commas 可以支持函數(shù)傳參尾逗號:

node -p 'function tc(a,b,) {}'   // 會報(bào)錯(cuò),因?yàn)樽詈笠粋€(gè)逗號
=========================
node --harmony_trailing_commas -p 'function tc(a,b,) {}' //不會報(bào)錯(cuò)

libuv

  1. libuv 提供了和操作系統(tǒng)交互的能力,比如說操作文件,網(wǎng)絡(luò)等等,并且磨平了操作系統(tǒng)的差異。

  2. node還使用libuv來處理異步操作,比如非阻塞IO(file system/TCP socket/child process)。當(dāng)異步操作完成時(shí),node通常需要調(diào)用回調(diào)函數(shù),當(dāng)調(diào)用回調(diào)函數(shù)時(shí),node會把控制權(quán)交給V8引擎。當(dāng)回調(diào)函數(shù)執(zhí)行完畢,控制權(quán)從v8引擎重新回到node.

    v8 引擎是單線程的,當(dāng)v8引擎獲得控制權(quán)的時(shí)候,node 只能等待v8 引擎操作完成。

    這讓node沒有死鎖,競爭的概念。

  3. libuv 包含一個(gè)線程池,從操作系統(tǒng)的層面來做那些不能被異步做的事情

  4. libuv 給node 提供了 event-loop, 會在第二節(jié)介紹

其他依賴

除了v8引擎和 libuv, node 還有其他的一些比較重要的依賴。

圖片

http-parser 用來解析http內(nèi)容的

c-ares 是用來支持異步的DNS 查詢的

openSSL 常用在 tls 和 crypto 的包中,提供了加密的方法

zlib 是用來壓縮和解壓的

node REPL

你可以在terminal里面執(zhí)行node來啟動CLI,如下所示,REPL十分方便

例如,你定義一個(gè)array,當(dāng)你arr.然后tab-tab(tab兩次),array自身的方法會顯示出來

? node
 var arr = []
undefined
 arr.
arr.toString              arr.valueOf
arr.concat                arr.copyWithin         arr.entries               arr.every              arr.fill                  arr.filter
arr.find                  arr.findIndex          arr.forEach               arr.includes           arr.indexOf               arr.join
arr.keys                  arr.lastIndexOf        arr.length                arr.map                arr.pop                   arr.push
arr.reduce                arr.reduceRight        arr.reverse               arr.shift              arr.slice                 arr.some
arr.sort                  arr.splice             arr.unshift

你也可以輸入.help,然后可以看到各種快捷鍵如下:

 .help
.break    Sometimes you get stuck, this gets you out
.clear    Alias  .break
.editor   Enter editor mode
.exit     Exit the repl
.help     Print this  message
.load     Load JS from a file into the REPL session
.save     Save all evaluated commands  this REPL session to a file

你還可以用_(underscore)來得到上次evaluated的值:

 3 - 2
1
 _
1
 3  2

 _

你還可以自定義REPL選項(xiàng),如下,你自定義repl.js并選擇忽視undefined,這樣output里面就不會有undefined輸出,同時(shí)你還可以預(yù)先加載你需要的library比如lodash

   
    :
? node /repl.js
 var i = 2

你可以用下面的command來查看更多的選項(xiàng) node --help | less

-p, --print     evaluate script and print result

-c, --check     syntax check script without executing

-r, --require   module to preload (option can be repeated)

例如,node -c bad-syntax.js可以用來檢查語法錯(cuò)誤, node -p 'os.cpus()'可以用來執(zhí)行script并輸出結(jié)果,你還可以傳入?yún)?shù),如下所示

? node -p   666
[ ,  ]

node -r babel-core/register可以用來預(yù)加載,相當(dāng)于require('babel-core/register')

global 中的 process 和 buffer

global相當(dāng)于瀏覽器里面的window,你可以global.a = 1;這樣a就是全局變量,但一般不推薦這樣做

global 對象身上有兩個(gè)屬性特別重要: process 和 buffer

process

processapplicationrunning env之間的橋梁,可以得到運(yùn)行環(huán)境相關(guān)信息,如下所示:

 process.
process.arch
process.argv
process.argv0                       process.assert                      process.binding
process.chdir
process.config                      process.cpuUsage
process.cwd                         process.debugPort
process.dlopen                      process.emitWarning
process.env                         process.execArgv
process.execPath
process.exit                        process.features                    process.getegid
process.geteuid                     process.getgid                      process.getgroups                   process.getuid
process.hrtime                      process.initgroups
process.kill                        process.memoryUsage
process.moduleLoadList              process.nextTick                    process.openStdin
process.pid
process.platform                    process.reallyExit                  process.release                     process.setegid
process.seteuid                     process.setgid                      process.setgroups                   process.setuid
process.stderr                      process.stdin                       process.stdout
process.title
process.umask                       process.uptime                      process.version                     process.versions
process._events                     process._maxListeners               process.addListener                 process.domain
process.emit                        process.eventNames                  process.getMaxListeners             process.listenerCount
process.listeners
process.on
process.once                        process.prependListener
process.prependOnceListener         process.removeAllListeners          process.removeListener              process.setMaxListeners\

process.versions 非常有用:

process.env 提供了當(dāng)前環(huán)境的一些信息

建議從 process.env 中只讀,因?yàn)楦牧艘矝]有用。

同時(shí),process也是一個(gè)event emitter,例如:

process.on('exit', code => {
// 并不能阻止node進(jìn)程退出
console.log(code)
})

process.on('uncaughtException', err => {
console.error(err)
process.exit(1)
})
  1. 在process 的事件處理函數(shù)中,我們只能執(zhí)行同步的方法,而不能使用event_loop,

  2. exit 和 uncaughtException 的?區(qū)別。如果uncaughtException 注冊了事件,則node遇到錯(cuò)誤并不會退出,也就是說,不會觸發(fā)exit 事件。這會讓node的執(zhí)行變的不可預(yù)測。證明如下:

    process.on('exit', (code) => {
    console.log('ssss')
    })
    process.on('uncaughtException', (err) => {
    console.error(err);
    })
    // keep the event loop busy
    process.stdin.resume()

    // 在這里觸發(fā)了bug
    console.logg()

    上面的代碼即使遇到了錯(cuò)誤也不會退出執(zhí)行,exit 事件處理函數(shù)并不會觸發(fā)。所以需要我們手動觸發(fā) process.exit(1) 才可以。

buffer

buffer 也是 global 對象中的一個(gè)屬性,主要用來處理二進(jìn)制流。 buffer 本質(zhì)上是一段內(nèi)存片段,是放在v8引擎的堆的外面。

我們可以在buffer 這個(gè)內(nèi)存中存放數(shù)據(jù)。

從 buffer讀取數(shù)據(jù)時(shí),我們必須指定encoding, 因此從 files 和 sockets 中讀取數(shù)據(jù)時(shí),如果不指定encoding, 我們會得到一個(gè) buffer 對象。

一旦buffer 被創(chuàng)建,就不能修改大小

buffer 在處理讀取文件,網(wǎng)絡(luò)數(shù)據(jù)流的時(shí)候非常有用

創(chuàng)建buffer的三種方式:

  1. Buffer.alloc(2)

    在內(nèi)存中劃分出固定的大小

  2. Buffer.allocUnsafe(8)

    沒有指定具體的數(shù)據(jù),可能會包含老的數(shù)據(jù)和敏感的數(shù)據(jù),需要被正確的『填充』

  3. Buffer.from()

buffer的方法

和數(shù)組類似,但是不同。比如說 slice 方法截取出來的新buffer 和 老的buffer是共享同一個(gè)內(nèi)存。

stringDecode

當(dāng)轉(zhuǎn)變二進(jìn)制數(shù)據(jù)流的時(shí)候,toString() 不如使用 stringDecode 模塊,因?yàn)樵撃K可以處理不完整的數(shù)據(jù)呢。

Require() 的背后

如果想深入了解node, 必須要深入了解 require 方法。

涉及到兩個(gè)核心模塊——require 方法(在grobal對象上,但是每一個(gè)模塊都有自己的require 方法) 和 Module 模塊 (同樣在grobal對象上,用來管理模塊的)

require 分為幾步

圖片

當(dāng)我們r(jià)equire一個(gè)module時(shí),整個(gè)過程有五個(gè)步驟:

Resolving 找到module的絕對文件路徑

Loading 將文件內(nèi)容加載到內(nèi)存

Wrapping 給每個(gè)module創(chuàng)造一個(gè)private scope并確保require對每個(gè)module來說是local變量

Evaluating VM執(zhí)行module代碼

Caching 緩存module以備下次使用

module 對象

 
  : 
  : 
  : undefined
  : 
  : 
  : 
  :

在Module對象里面,id 是module的identity,通常它的值是module文件的全路徑,除非是root,這時(shí)它的值是.(dot)

filename 是文件的路徑

paths 從當(dāng)前路徑開始,往上一直到根路徑

require.resolve 和require一樣,但是它不會加載文件,只是resolve

模塊不一定是文件?

  1. 可以是文件,比如說 node_module/find-me.js

  2. 可以是目錄帶index.js,比如說 node_module/find-me/index.js

  3. 可以是目錄帶package.json, 比如說node_module/find-me/main.js

        : 
        :

exports 屬性

exports 是module 上一個(gè)特殊的屬性,我們放入它的任何變量都可以在require時(shí)得到 。

loaded

Module對象的loaded屬性會保持false,直到所有content都被加載

因此,exports 不能放在的異步的setImmediate 中

循環(huán)引用

例如A require B,B require A

JSON 文件 和 c++ Addon 文件

Node會首先查找.js文件,再查找.json文件,最后.node文件 比如說,在主文件中,引入.json 文件

// 在主文件中
let mock = require('mockData.json')
console.log(mock)

mockData.json 文件中,不需要導(dǎo)出什么,直接寫json格式的即可

{
    : ,
    : ,
}

如果node找不到 .js , .json 文件,就會找.node 文件,會把.node 文件作為一個(gè)編譯好的addon(插件) module。那么 .node 文件是從哪里來的呢?

  1. 先有一個(gè) hello.cc 文件,是用 c++ 代碼寫的

  2. ?再有一個(gè) binding.gyp, 相當(dāng)于的編譯的配置文件,里面是json 格式的配置項(xiàng), 如下面所示:

    {
      : [
        {
          : ,
          : [  ]
        }
      ]
    }
  3. 安裝 npm install node-gyp -g , node 和 npm 自帶的那個(gè)不是給開發(fā)者?用的,而是需要重新安裝一個(gè)

  4. node-gyp configure 根據(jù)平臺生成項(xiàng)目,再執(zhí)行node-gyp build 生成 .node 文件,可以在 js的代碼中直接引用使用了。

    你可以通過require.extensions來查看Node支持的文件擴(kuò)展名:

> require.extensions
{ '.js': [Function], '.json': [Function], '.node': [Function] }

圖片

上面的代碼中,對于 .js 文件,是直接編譯引入,對于.json 文件,是使用了JSON.parse 方法,對于 .node 文件,是使用了 process.dlopen() 方法。

包裹模塊

     

  
    :         


  
    :

上面的代碼中,為什么exports 和 module.exports 有區(qū)別?

原因是,node 引入一個(gè)模塊代碼后,node 會給這些代碼外面包裹上一層方法,這個(gè)方法是module 模塊的wrapper 方法:

 require().wrapper
[ ,
   ]

這個(gè)方法接受5個(gè)參數(shù): exportsrequiremodule__filename__dirname

這個(gè)方法,讓 exportsrequiremodule 看起來是全局變量,但其實(shí)是每個(gè)文件所獨(dú)有的。

exports 是 module 對象的module.exports 方法的引用,相當(dāng)于 let exports s = module.exports, 如果讓 exports = {} 等于讓 exports 變量改寫了引用

緩存模塊

當(dāng)?shù)诙我胪粋€(gè)文件的時(shí)候,將會走了緩存。

console.log(require.cache)
delete require.cache['/User/sss/sss/cache.js']

下一期我們再見~

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    主站蜘蛛池模板: 天天躁躁水汪汪人碰人| 中文字幕人妻三级中文无码视频| 欧美大片18禁aaa免费视频| 午夜成人精品福利网站在线观看| 亚洲另类激情综合偷自拍图片| 国产成人精品日本亚洲直接| 精品国产你懂的在线观看| 成人影片一区免费观看| 99久久国语露脸精品国产色| 波多野结衣免费一区视频| 一本色道久久综合狠狠躁| 国产乱子伦高清露脸对白| 国产精品人妻一码二码| 欧美性猛交内射兽交老熟妇| 国产精品久久国产精品99盘| 亚洲精品国产av成拍色拍| 亚洲 中文 欧美 日韩 在线| 脱岳裙子从后面挺进去在线观看| 亚洲综合精品第一页| 国产真实乱子伦清晰对白| 精品少妇一区二区三区免费观| 亚洲中文字幕无码一久久区| 久久亚洲精品中文字幕一区| 久久亚洲中文字幕精品一区| 无码中文精品专区一区二区| 欧美va天堂在线电影| 性饥渴的少妇av无码影片| 少妇人妻诗雨系列无删减| 亚洲成在人线免费观看| 免费无码国模国产在线观看| 亚洲av综合色区无码二区爱av| 亚洲色大成网站www久久九九| 国产成人精品免高潮在线观看| 久久精品国产久精久精| 2021国产精品视频网站| 亚洲午夜无码毛片av久久京东热| 国产一区二区三区四区五区vm| 精品国产午夜理论片不卡| 国产精品内射视频免费| 国产又黄又猛又粗又爽的a片动漫| 狼人大香伊蕉国产www亚洲|