成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Node 基礎學習

alaege / 2270人閱讀

摘要:既然這樣,怎么理解中的單線程再捋一捋和的關系。在線程上,不會等待操作完成,繼續(xù)執(zhí)行后續(xù)的代碼。這就是單線程異步。在中除了代碼,一切都是并行的由于中主任務的執(zhí)行是以單線程的方式進行,如果程序出錯導致崩潰,就會終止整個流程。

node是什么

Node.js 是一個基于 Chrome V8 引擎的 JavaScript 運行環(huán)境。

Node.js 使用了一個事件驅(qū)動、非阻塞式 I/O 的模型。

Node使用包管理器NPM。

第一句話
Node.js 是一個基于 Chrome V8 引擎的 JavaScript 運行環(huán)境。

運行環(huán)境, 不是一門語言,不是一個框架。只是能夠作為JavaScript代碼運行的一個環(huán)境。

而這個運行環(huán)境主要是由V8提供的。

V8做了什么?

創(chuàng)建了一個callstack。

function main(){
    func1();
}
function func1(){
    func2();
}
function func2(){
    console.log(1);
}
main();

除去V8,Node中還有哪些東西?

除去V8,Node中另外一個比較重要的組成就是 libuv。

What? libuv是什么鬼?

先說說,關于Node的另外一句話:

Node is designed to build scalable network applications.

這句話的底氣在哪兒,就是Node本身采用的 事件驅(qū)動,非阻塞I/O模型。

并發(fā)模型構建網(wǎng)絡的應用中,每個連接都會生成一個新線程,每個新線程可能需要 2MB 的配套內(nèi)存。在一個擁有 8 GB RAM 的系統(tǒng)上,理論上最大的并發(fā)連接數(shù)量是 4,000 個用戶。隨著您的客戶群的增長,如果希望您的 Web 應用程序支持更多用戶,那么,您必須添加更多服務器。所以在傳統(tǒng)的后臺開發(fā)中,整個 Web 應用程序架構(包括流量、處理器速度和內(nèi)存速度)中的瓶頸是:服務器能夠處理的并發(fā)連接的最大數(shù)量。這個不同的架構承載的并發(fā)數(shù)量是不一致的。而且,多個線程存在的話,也會衍生出線程切換的問題,這也會占用一定資源。

并發(fā)存在的兩個問題:

Execution stacks take up memory: 資源有限

Context switching is not free:占用額外資源

Node的解決這個問題思路:

在網(wǎng)絡應用中,比較慢的環(huán)節(jié)主要在 磁盤讀取 或 網(wǎng)絡請求階段,這時候CPU處于閑置狀態(tài)。

如果在等待I/O操作時,能夠釋放處于閑置狀態(tài)的CPU,則可以很大程度上利用資源;

那么接下來的問題就在于,如何在I/O 操作完成后,繼續(xù)執(zhí)行后續(xù)的操作;

解決方案:事件驅(qū)動,采用回調(diào)。這和瀏覽器中的Event Loop是一樣的道理。

市場上已經(jīng)有一些使用同樣處理思路的框架。

EventMachine:處理網(wǎng)絡請求的框架,主要是面向ruby;

Twisted:用Python實現(xiàn)的基于事件驅(qū)動的網(wǎng)絡引擎框架;

具體是怎么做的?

在程序運行時,V8 會把I/O操作等耗時較多操作及相關回調(diào)一并交給libuv去處理。而V8繼續(xù)執(zhí)行后面的代碼。等到I/O操作完成后,libuv會將回調(diào)方法放到事件隊列中。

const fs = require("fs");

const readFile = (file) => {
    fs.readFile(file, (err, data) => {
        if(!err) console.log(data);
    });
}

console.log("program start ......");
readFile("file.json");
console.log("readFile has put the I/O ");
console.log("program end!!!!!");

負責異步程序調(diào)度的工作就是libuv做的事情。

Libuv is a multi-platform support library with a focus on asynchronous I/O.

在上述程序中,當遇到文件讀取操作時,V8會把js接口轉(zhuǎn)成C++接口 同時把回調(diào)方法一并交給libvu。此時libuv接管這個文件讀取任務。當文件讀取完成后,libuv就會把這個事件的回調(diào)函數(shù)扔到事件隊列里。當下一次檢查事件隊列時,就會執(zhí)行該回調(diào)函數(shù)。

question: 既然這樣,怎么理解node中的單線程?

再捋一捋Node, V8 和libuv的關系。

1) Node主要由V8 javascript引擎和libuv組成;
2) v8引擎主要負責解釋執(zhí)行js代碼,碰到需要異步的操作會交給libuv處理;
3) libuv本身是獨立的c語言庫,可以直接使用c/c++來調(diào)用;

在瀏覽器端,JS是沒有能力進行文件讀取操作的。js最初的能力也就限制在表單校驗上。而在Node中,JS可以操作本地文件,建立網(wǎng)絡連接。這肯定是Node干的好事!

再來說說Node中其它一些組成部分

Node擴展了JS的能力:builtin modules

builtin modules是由C++代碼寫成各類模塊,包含了crypto,zlib, file, net等基礎功能。

native modules

除了builtin modules, 還有一個native modules。它們是用js編寫的內(nèi)建模塊,提供給程序開發(fā)者使用。

fs

http

builtin modules 和 native modules都屬于核心模塊。核心模塊在Node源碼編譯的過程中,編譯進了二進制文件。所以在Node進程啟動的時候,部分核心模塊就已經(jīng)被直接加載到了內(nèi)存當中。

至此,Node的基本構成和運行原理已經(jīng)講完了。


補充一句:Node.js的單線程并不是真正的單線程,只是開啟了單個線程(可以定義為主線程)進行業(yè)務處理,同時開啟了其他線程專門處理I/O。當一個指令到達主線程,主線程發(fā)現(xiàn)有I/O之后,直接把這個事件傳給libuv處理。libuv會管理一個線程池,I/O操作就是由線程池里面的線程完成的。等I/O 操作完成,libuv,會把對應I/O操作的回調(diào)放到事件循環(huán)當中。在線程上,不會等待I/O 操作完成,繼續(xù)執(zhí)行后續(xù)的代碼。這就是“單線程”、“異步I/O”。

IO.js

var fork = require("child_process").fork;
var fs = require("fs");

console.log("start......");

// blocking
// console.log(fs.readFileSync("test.json", "utf-8"));

// non blocking
var childProcess = fork("another-thread.js");
childProcess.on("message", function(data){
    console.log(data);
})

console.log("end !!!");

another-child.js

var fs = require("fs");
process.send( fs.readFileSync("test.json", "utf-8"));
Everything runs in parallel except your code!  在Node中)除了代碼,一切都是并行的!

由于node中主任務的執(zhí)行是以單線程的方式進行,如果程序出錯導致崩潰,就會終止整個流程。為此,市場上有些Node進程管理工具,它們會維護Node程序的狀態(tài),當程序掛掉時,會自動重啟。比如我們使用的pm2。

NPM

對于node沒有的一些模塊(native modules),可以引入外部模塊。這些外部模塊通常是其它開發(fā)者貢獻的。

那么問題來了,對于數(shù)量眾多的模塊中,如何快速找到自己想要的并能夠快速的引進到自己的項目當中。

這就是npm幫我們做的工作。

Use npm to install, share, and distribute code; manage dependencies in your projects; and share & receive feedback with others.

npm官網(wǎng)

模塊安裝:

模塊共享

發(fā)布代碼

管理依賴

共享和反饋

NPM的基本模式

NPM是JavaScript包的管理器。

廣義的npm的構成

npm consists of three distinct components:

the website: NPM官方站點

the Command Line Interface (CLI) : NPM命令行工具

the registry: JS模塊的數(shù)據(jù)庫

Use the website to discover packages, set up profiles, and manage other aspects of your npm experience. For example, you can set up Orgs (organizations) to manage access to public or private packages.

The CLI runs from a terminal. This is how most developers interact with npm.

The registry is a large public database of JavaScript software and the meta-information surrounding it.

npm中的使用

npm默認隨node一起安裝,在Node安裝完成后,npm已經(jīng)安裝。

查找一個包

去npm官網(wǎng),按關鍵詞查找。

管理模塊

npm install [module name] :普通安裝方式,包安裝完成后,會在當前目錄生成一個node_modules目錄。這是一個存放外部js模塊的地方,通過npm安裝的包都放在node_modules下。

npm install -g [module name]:全局安裝,模塊被安裝在node安裝路徑下的 node_modules中。

npm install [folder path]:可以指定npm 安裝某個目錄folder path下的的文件,前提是這個目錄下包含package.json文件。

npm install [module name]@[version]: 安裝包的時候,指定對應的版本號。

npm isntall chalk@latest : 安裝最新版

npm install chalk@2.0.0: 安裝2.0.0版

npm install chalk@">=2.0.0":安裝大于2.0.0的版本

npm install --save-prod [module name]: 在本地安裝包,并將安裝信息寫入 package.json文件中的dependencies中, 不寫--save-prod 或者只寫 --save 默認跟 --save-prod一樣。

npm install --save-dev [module name]:在本地安裝包,并將安裝信息寫入 package.json文件中的devDependencies

dependencies:在生產(chǎn)環(huán)境中需要用到的依賴

devDependencies:在開發(fā)、測試環(huán)境中用到的依賴

npm update [module name]: 更新本地模塊

npm uninstall [module name]: 卸載模塊

package.json

package.json是一個node和npm都會自動讀取的配置文件,它里面是個標準的JSON格式字符串。

對于NPM而言, package.json做了以下工作:

存儲項目依賴的所有包

允許你指定項目依賴的包的版本規(guī)則,不滿足項目需求的版本,不需要

讓你的項目構建具有可復用性,容易分享你的項目

對于你的項目而言,package.json定義了一些基礎信息,比如項目名稱,版本等等。

pakcage.json必須具有的兩個字段: nameversion。這倆個字段有什么意義呢?
NPM 作為一個包管理平臺,當有開發(fā)者提交(publish)模塊時,必須提供一些基本信息便于管理。

name: 項目名稱或者模塊名稱

version:版本號,應當遵循 x.x.x的格式

description:項目信息描述,方便別人了解你的模塊,也利于搜索

keywords:項目的關鍵詞,便于搜索

homepage:項目的主頁;

scripts:scripts屬性是一個對象,里面的每一個屬性對應一段腳本;腳本可以使用 npm run + 屬性名 執(zhí)行

main:指定項目的程序入口文件,該文件的exports對象同時也是require項目時,取到的對象。

repository:指明代碼存在的地址,便于別人更好的查看你的源碼

dependencies:一個對象,配置模塊依賴的模塊列表,key是模塊名稱,value是版本描述(遵循semantic規(guī)則)

devDependencies:一個對象,開發(fā)或測試過程中的一些依賴模塊,跟上線后的依賴模塊區(qū)分出來

engines: 指定項目運行的Node版本

author:項目的開發(fā)者

contributors:一堆項目的開發(fā)者

{
  "name": "vue-todo",
  "version": "1.0.0",
  "description": "a simply todolist using vuejs",
  "scripts": {
    "start": "node server.js",
    "stop": "egg-scripts stop --title=egg-server-example",
    "dev": "egg-bin dev"
  },
  "dependencies": { // 線上生產(chǎn)環(huán)境必須,當然開發(fā)環(huán)境也會用到
    "babel-runtime": "^6.23.0",
    "vue": "^2.0.1",
    "vue-localstorage": "^0.1.1",
    "vuex": "^2.2.1"
  },
  "devDependencies": { // 開發(fā)環(huán)境會用到的東東
    "webpack": "^1.13.2",
    "webpack-dev-middleware": "^1.8.3",
    "webpack-hot-middleware": "^2.12.2",
    "webpack-merge": "^0.14.1"
  }
}
semantic versioning(語義化版本規(guī)則)

版本格式:主版本號.次版本號.修訂號, 例如 1.2.3

版本號遞增規(guī)則如下:

主版本號:當你做了不兼容的 API 修改; 1.2.3 ---> 2.0.0

次版本號:當你做了向下兼容的功能性新增; 1.2.3 ---> 1.3.0

修訂號:當你做了向下兼容的問題修正; 1.2.3 ---> 1.2.4

在package.json定義版本規(guī)則的時候,可以這么做:

如果只打算接受補丁版本的更新(也就是最后一位的改變),就可以這么寫:

1.0

1.0.x

~1.0.4

如果接受小版本的更新(第二位的改變),就可以這么寫:

1

1.x

^1.0.4

如果可以接受大版本的更新(自然接受小版本和補丁版本的改變),就可以這么寫:

*

x

在使用npm install --save || npm install --save-dev 安裝的時候,寫入pakcage.json中的依賴,默認接受小版本的更新,即在版本號前添加 "^"。

NPM document

Node 模塊

Node中的模塊分為兩類:

核心模塊(Node中內(nèi)嵌的,比如fshttp等)

文件模塊(開發(fā)者自己編寫的,NPM上的模塊都屬于開發(fā)者自定義的模塊)

文件模塊是在運行的時候,動態(tài)加載。需要進行路徑分析,文件定位 和 編譯執(zhí)行。

Node加載模塊時,優(yōu)先從緩存中加載,如果緩存中不存在該模塊,才會按照上述的三個步驟進行模塊加載。

模塊標識符在Node中,主要有以下幾類:

核心模塊,比如fs, http

...開頭的相對路徑文件模塊

/ 開頭的絕對路徑文件模塊

非路徑形式的文件模塊;

這幾類模塊的加載速度是依次降低的。

module.js

同瀏覽器中的window一樣,在Node中的全局變量都掛在global下。
先說一下,常用到一些變量:

__dirname: 當前模塊所在目錄

__filename: 當前模塊文件名稱

require: 引入其它模塊

module:

exports

上面5個變量,貌似全局變量,但不是全局變量。他們都是模塊系統(tǒng)下的東西。

question: 它們不在全局變量下,那它們?yōu)楹慰梢栽谀K中直接調(diào)用?

Node引入模塊

在Node中,引入模塊分為三個步驟:

路徑分析

文件定位

編譯執(zhí)行

模塊編譯

編譯和執(zhí)行是引入文件模塊的最后一個階段。

.js文件 : Node 會對js源碼進行一個首尾的封裝。返回一個function,并將當前的環(huán)境的exports,require,module,__dirname,__filename作為形參傳遞給這個function。

包裝后的代碼:

(function(exports, require, module, __filename, __dirname){
    // js文件中的源碼
})

這就是為什么 它們不在 全局變量下,卻可以在模塊當中使用的原因。

.node文件: 對于.node文件, 實際上并不需要編譯過程。因為.node文件本身就是C/C++編譯后的文件,它只有加載和執(zhí)行過程。

.json文件: Node 會讀取json文件內(nèi)容,并將它賦予exports對象,直接傳遞給第三方調(diào)用。

在NPM中的模塊,基本屬于Node中文件模塊里的Javascript模塊。

require的規(guī)則

Node的模塊系統(tǒng)參照CommonJS規(guī)范實現(xiàn)。

如果參數(shù)字符串不以.//../開頭,說明要加載的不是一個文件,而是一個默認提供的核心模塊。

此時則先在node平臺所提供的核心模塊當中找;

然后再尋找NPM模塊(即第三方模塊包,或自己寫的模塊包)

在尋找NPM模塊包時,會從當前目錄出發(fā),向上搜索各級當中的node_modules文件夾當中的文件,但若有兩個同名文件,則遵循就近原則。(module.paths是一個模塊路徑數(shù)組。)

如果require當中的參數(shù)字符串以/開頭:則表示從系統(tǒng)根目錄開始尋找該模塊文件。

如果require當中的參數(shù)字符串以./(從當前目錄出發(fā))或../(從上一級目錄出發(fā))開頭:表示按照相對路徑,從當前文件所在的文件夾開始尋找要載入的模塊文件。

按js文件來執(zhí)行(先找對應路徑當中的module.js文件來加載)

按json文件來解析(若上面的js文件找不到時,則找對應路徑當中的module.json文件來加載)

按照預編譯好的c++模塊來執(zhí)行(尋找對應路徑當中的module.node文件來加載)

若參數(shù)字符串為一個目錄(文件夾)的路徑,則自動先查找該文件夾下的package.json文件,然后再再加載該文件當中main字段所指定的入口文件。(若package.json文件當中沒有main字段,或者根本沒有package.json文件,則再默認查找該文件夾下的index.js文件作為模塊來載入。)

process

process 對象是一個全局變量,它提供當前 Node.js 進程的有關信息,以及控制當前 Node.js 進程。

process.argv: 包含命令行參數(shù)的數(shù)組。第一個元素會是"node",第二個元素將是.js文件的名稱,接下來的參數(shù)依次是命令行參數(shù)

process.execArgv: 啟動進程所需的 node 命令行參數(shù)。這些參數(shù)不會在 process.argv 里出現(xiàn),并且不包含 node 執(zhí)行文件的名字,或者任何在名字之后的參數(shù)。這些用來生成子進程,使之擁有和父進程有相同的參數(shù)

process.env: 獲取當前系統(tǒng)環(huán)境信息的對象,輸出內(nèi)容是環(huán)境變量等內(nèi)容,這個對象可以修改

nextTick(callback): 將callback放到事件輪詢隊列首位,下一次事件輪詢開始時,先執(zhí)行callback

process.abort:結束當前進程

process.kill(pid):結束一個進程

process.js

console.log(process.argv);
console.log(process.execArgv);
node process.js
# [ "/usr/local/bin/node", "/root/node-demo/process.js" ]
# []

node process.js abc 234 cvb=cvb
# [ "/usr/local/bin/node",
#   "/root/node-demo/process.js",
#   "abc",
#   "234",
#   "cvb=cvb" ]
# []


node --harmony  --use-openssl-ca  process.js abc 234 cvb=cvb
# [ "/usr/local/bin/node",
#   "/root/node-demo/process.js",
#   "abc",
#   "234",
#   "cvb=cvb" ]
# [ "--harmony", "--use-openssl-ca" ]

Node"Process document

fs

file.js

Node"FileSystem document

questions require("../fs/file.js")這里是異步還是同步?

deno,下一代Node?

package.json

node_modules

gyp

等等............

Node之父JS大會介紹deno時的PPT(2018)

Node之父JS大會介紹Node時的PPT(2009)

Nodejs的運行原理-科普篇

視頻:callstack 和異步 基本原理

Awesome Micro npm Packages

libuv 官網(wǎng)

[深入淺出Node.js]()

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/98694.html

相關文章

  • JAVA基礎整理(五)---手寫簡單的linkedlist來學習linkedlist

    摘要:類鏈表容器也是通過對比源碼進行對比學習。增加一個結點不帶,直接尾插法當鏈表里沒有一個元素時,頭尾都是該結點,并且該結點的前后都是空的。尾結點是該結點的前驅(qū)結點,該結點是尾節(jié)點的后繼結點,更新尾節(jié)點。 LinkedList類 鏈表容器也是通過對比jdk源碼進行對比學習。 1.定義結點類型 class Node{ E item; Node next; Node prev; Node(No...

    dantezhao 評論0 收藏0
  • 學習Vue2.0的建議順序

    摘要:官方文檔官方文檔,官方文檔永遠是學習資料的第一步起步扎實的基本功。學習的新特性,理解,建議可以看看阮一峰的教程。的學習曲線會比較長,需要了解到的常用命令,以及和的模塊規(guī)范,的也很多,其實更多的是屬于一項后端語言。 學習Vue2.0的建議順序 注:本文是看過其他關于vue文章之后的想法,歡迎轉(zhuǎn)載,請注明出處。   Vue官方文檔:Vue2.0官方文檔,官方文檔永遠是學習資料的第一步 起步...

    iamyoung001 評論0 收藏0
  • JAVA基礎整理(六)---手寫簡單的HashMap來學習hashmap

    摘要:學習手動寫一個簡單的進行理解結點的定義的基礎時一個數(shù)組,數(shù)組里每個元素是一個,他必須包括值,鍵值,,下一個結點,同一個值的結點用一條鏈栓起來。第一個結點的特殊操作第一個對上了修改一個元素查找一個元素 HashMap學習--手動寫一個簡單的HashMap進行理解 1.結點Node的定義 public class Node { public int hash; public...

    Travis 評論0 收藏0
  • 十步零基礎JavaScript學習路徑

    摘要:之前寫過一篇天學通前端開發(fā),內(nèi)容主要講的就是前端學習路徑,今天再來寫一篇零基礎的學習路徑,希望能幫編程零基礎的前端愛好者指明方向。十框架三選一,零基礎的初學者強烈推薦,如果是后臺轉(zhuǎn)前端推薦,如果技術型前端,推薦。 之前寫過一篇26天學通前端開發(fā),內(nèi)容主要講的就是前端學習路徑,今天再來寫一篇零基礎的JavaScript學習路徑,希望能幫編程零基礎的前端愛好者指明方向。 一、開發(fā)環(huán)境和Ja...

    incredible 評論0 收藏0
  • node學習系列之基礎(二)

    摘要:由于這種特性,某一個任務的后續(xù)操作,往往采用回調(diào)函數(shù)的形式進行定義。另外,回調(diào)函數(shù)本身的第一個參數(shù),約定為上一步傳入的錯誤對象。這種寫法有一個很大的好處,就是說只要判斷回調(diào)函數(shù)的第一個參數(shù),就知道有沒有出錯,如果不是,就肯定出錯了。 REPL環(huán)境 在命令行鍵入node命令,后面沒有文件名,就進入一個Node.js的REPL環(huán)境(Read–eval–print loop,讀取-求值-輸出...

    zhaot 評論0 收藏0
  • 教你如何打好根基快速入手react,vue,node

    摘要:謹記,請勿犯這樣的錯誤。由于在之前的教程中,積累了堅實的基礎。其實,這是有緣由的其復雜度在早期的學習過程中,將會帶來災難性的影響。該如何應對對于來說,雖然有大量的學習計劃需要采取,且有大量的東西需要學習。 前言倘若你正在建造一間房子,那么為了能快點完成,你是否會跳過建造過程中的部分步驟?如在具體建設前先鋪設好部分石頭?或直接在一塊裸露的土地上先建立起墻面? 又假如你是在堆砌一個結婚蛋糕...

    ddongjian0000 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<