nodejs-基礎大雜燴(待整理)

優勢:安裝簡易,能自動配置環境變量
缺點:更新和更換版本需從新安裝(這個能夠用包管理器解決,不是問題)

高手推薦使用開源的NVM包管理器來更新和安裝node,可能這個包在linux平臺上比較好用吧javascript


globaljava

requirenode

modulelinux

processgit

這些都是在node中能用而在google瀏覽器中很差用的功能angularjs

windowsgithub

locationweb

documentredis

consolemongodb

這些是在google瀏覽器中好用的功能



var relay = require('./relay');

這條語句尋找的,要麼是relay.js,要麼是relya/index.js

var os = require('os');

os的object在node的系統定義裏面


經常使用開發工具

webstorm

sublime text

linux

redis

mongodb

這些工具均可以在windows上實現

集成開發環境可使用vs code or vs


node服務器特色

1.不依賴其餘特定的服務器軟件(如apache、Nginx、IIS )

2.node.js 代碼處理請求的邏輯

3.node.js 代碼負責web服務器的各類「配置」



三種簡單的路由方法:

1.path

2.Router

3.route


中間件技術:

1.Connect : node.js的中間框架

2.分層處理

3.每層實現一個功能


node.js核心功能

1.node是一個js的執行環境,其實是對V8的封裝,使得V8在非瀏覽器的環境下執行的更好

2.node對一些特殊用例進行了優化

3.提供了替代的API

4.nodejs使用事件驅動,非阻塞I/O模型而得以輕量和高效

5.很是合適在分佈式設備上運行的數據密集型的實時應用


Nodejs優勢或特色

1.Restful API

2.單線程(這是一個坑,國內技術文章誤傳)

3.node能夠在不新增線程的狀況下,依然能夠對任務進行並行處理

4.它經過事件輪詢(event loop ) 處理請求

5.儘量的避免阻塞操做,取而代之,多使用非阻塞操做

6.支持websocket

7.不容許用戶鎖上程序

8.要求用戶不斷的處理新事物,所以很適合網絡編程

9.在服務器上要與不少客戶端通訊,必須處理網絡連接

10.node開發服務器比傳統語言更加方便


express

1.一個基於nodejs平臺的靈活、簡潔的應用開發框架

2.提供強大的特性,幫助建立各類web和移動應用

3.豐富的HTTP快捷方法和任意排列組合的Connect中間件,讓建立健壯、友好的API變的快速又簡單

4.Express不對nodejs已有的特性進行二次抽象,只是在其上擴展了web應用所須要的基本功能


關鍵詞:

express開發框架相似於ASP.NET MVC框架

jade模版引擎相似於Razor引擎

stylus樣式框架:CSS預處理器,CSS框架

Mean全棧解決方案:mongodb+express+angularjs+nodejs


nodejs能夠用來

1.Web socket Server

2.Fast file upload client

3.ad server

4.any real-time data apps


Blocking-code   阻塞式代碼

non-Blocking-code 非阻塞式代碼



全局對象 : global

__dirname  :輸出的當前文件的路徑

__filename  :輸出當前文件的路徑和文件名

console

   console.log()

   console.info()

   console.error()

   console.warn()

   console.time()     

   consoel.timeEnd() 統計代碼的執行時間,配合console.time()使用

process 

   process.stdout   標準輸出  console.log調用的就是process.stdout.write("what")函數

   process.stderr   標準錯誤輸出

   process.stdin     讀取鍵盤輸入

1
2
3
4
process.stdin.setEncoding( 'utf-8' );
process.stdin.on( 'data' , function (data){
     console.log(data);
})
1
2
3
4
5
process.stdin.setEncoding( 'utf-8' );
process.stdin.on( 'readable' , function (){
        var data = process.stdin.read();
        console.log(data);
});

監聽退出事件

1
2
3
process.on( 'exit' ,funciton(){
       console.log( 'program will exit' );
})

監聽中斷事件 SIGINT --> signal interrupted 

1
2
3
process.on( 'SIGINT' ,funciton(){

      console.log('program will exit');

      process.exit();

})

   process.args

封裝了咱們在node中輸入的命令,以數組的形式展現,是 一個數組,第0項是node命令所在的目錄,第二項是當前文件所在的絕對文件路徑,第三項纔開始是具體的參數。。。。

1
console(process.args);


   process.cwd()  --->展現執行node命令所在的目錄

node的重定向命令

1
node console.js 1 >log.txt 2 > tt.txt

將第一條命令輸出內容輸出到log.txt

將第二條命令輸出內容輸出到tt.txt




object類型

   做用:功能相對單一,傳輸數據,保存數據和方法,以集合方式來組織

  初始化:構造函數方法,字面量方法

基本包裝類型

Global對象

Math對象



Ryan dahl 是nodejs之父

關於高性能服務器的思考

process 13MB

10GB / 13MB = 787併發


thread 2MB

10GB / 2MB = 5120併發


事件驅動  Event loop

  什麼是事件驅動,用戶發起的HTTP請求,點擊,打開文件,都是一個事件

單線程 / 全部用戶

資源消耗極小


Watcher

  向watcher詢問是否有事件須要處理

  timer watcher

  fs watcher 

  udp / req watcher 

  process watcher

Handles

  由watcher產生具體要處理的事件

  setTimeout

  當時間到達時,產生事件,執行handle(handle就是執行傳入的回調函數)

 

Event loop --> watcher --> handles 


爲何console.log()執行完成後退出

爲何http.server()能夠一直讓程序執行

當event loop 中沒有watcher的時候退出進程


Node中的Event Driven 實現

windows : IOCP 

Linux : epoll 

Mac : kqueue

Solaris : events ports


Event Driven 的問題

單線程阻塞的問題

一旦阻塞,事件的處理就變的低效


阻塞問題

磁盤 I/O 和 網絡 I/O 的訪問阻塞CPU執行

進行磁盤I/O和網絡I/O時,CPU浪費

後續計算沒法進行


沒有完美的非阻塞I/O,經過線程池結合事件驅動實現


選擇javascript緣由

1.成熟的事件驅動模式

2.沒有I/O庫,沒有歷史包袱,利於構建非阻塞的I/O庫


V8 

1.直接生成機器碼

2.分代式GC

3.優化




分層架構

引入libuv層

分別實現windows和linux平臺的功能

分別編譯


單線程服務大量的請i去

異常致使進程退出時,會丟失大量用戶請i求


單線程問題

1.多核CPU利用問題

2.不該該浪費服務器資源


進程間的消息傳遞

1.進程間不共享數據

2.經過消息傳遞信息



子進程 / Cluster


分離監控和業務

充分利用硬件資源




模塊

基於CommonJS Module 規範構建

公用模塊平臺 NPM


異步編程問題

Promise 

EventProxy

Async / Step 


在 C++或 C#中,當咱們談到對象,指的是類或者結構體的實例。對象根
據他們實例化的模板(就是所謂的類),會擁有不一樣的屬性和方法。但在
JavaScript 裏對象不是這個概念。在 JavaScript 中,對象就是一個鍵/
對的集合 -- 你能夠把 JavaScript的對象想象成一個鍵爲字符串類型的字
典。


但若是 JavaScript 的對象僅僅是鍵/值對的集合,它又怎麼會擁有方法呢?好吧,這裏的值能夠是字符串、數字或者……函數。


在瀏覽器中,頂級做用域爲全局做用域,在全局做用域下經過 var something即定義了一個全局變量。可是在 Node 中並不如此,頂級做用域並不是是全局做用域,在 Node 模塊中經過 var something 定義的變量僅做用於該模塊。


require.paths
require()的搜索路徑數組,你能夠修改該數組添加自定義的搜索路徑
將一個新的搜索路徑插入到搜索列表的頭部。
1
require.paths.unshift( '/usr/local/node' );
__filename
當前正在執行的腳本的文件名。這是一個絕對路徑,可能會和命令行參數中傳入的文件名不一樣。
1
2
console.log(__filename);
// /Users/mjr/example.js
__dirname
Timers 定時器
setTimeout(callback, delay, [arg], [...])
設定一個 delay 毫秒後執行 callback 回調函數的計劃。返回值 timeoutId 被用於 clearTimeout()。能夠設定要傳遞給回調函數的參數

clearTimeout(timeoutId)

setInterval(callback, delay, [arg], [...])
設定一個每 delay 毫秒重複執行 callback 回調函數的計劃。返回值
intervalId 可被用於 clearInterval()。能夠設定要傳遞給回調函數的參數。

clearInterval(intervalId)

Folders as Modules 目錄做爲模塊
第一種方法是在目錄的根下建立一個名爲 package.json 的文件,它指定了一個 main 模塊。一個 package.jso 文件的例子以下面所示:
1
2
{ "name" : "some-library" ,
"main" : "./lib/some-library.js" }
若是在目錄中沒有 package.json 文件, node 將試圖在該目錄中加載 index.js或 index.node 文件。例如,在上面的例子中沒有 package.json 文件,
require('./some-library')將試圖加載

1
2
 ./some-library/index.js
 ./some-library/index.node
Caching 緩存
模塊在第一次加載後將被緩存。這意味着(相似其餘緩存)每次調用
require('foo')若是解析到相同的文件,那麼將返回同一個對象

module
經過module對象能夠訪問到當前模塊的一些相關信息,但最多的用途是替換
當前模塊的導出對象。例如模塊導出對象默認是一個普通對象,若是想改爲一
個函數的話,可使用如下方式。
1
2
3
module.exports = function () {
      console.log( 'Hello World!' );
};

一個模塊中的JS代碼僅在模塊第一次被使用時執行一次,並在執行過程當中初始
化模塊的導出對象。以後,緩存起來的導出對象被重複利用。


NODE_PATH環境變量
與PATH環境變量相似,NodeJS容許經過NODE_PATH環境變量來指定額外的模塊搜索路徑。
NODE_PATH環境變量中包含一到多個目錄路徑,路徑之間在Linux下使用:分隔,在Windows下
使用;分隔。例如定義瞭如下NODE_PATH環境變量:
NODE_PATH=/home/user/lib:/home/lib

當使用require('foo/bar')的方式加載模塊時,則NodeJS依次嘗試如下路徑。
/home/user/lib/foo/bar
/home/lib/foo/bar


index.js
當模塊的文件名是index.js,加載模塊時可使用模塊所在目錄的路徑代替
1
2
var cat = require( '/home/user/lib/cat' );
var cat = require( '/home/user/lib/cat/index' );

1
2
3
function copy(src, dst) {
     fs.createReadStream(src).pipe(fs.createWriteStream(dst));
}

Buffer
1
var bin = new Buffer([ 0x68 , 0x65 , 0x6c , 0x6c , 0x6f ]);
1
bin[ 0 ]; // => 0x68;
Stream(數據流)
當內存中沒法一次裝下須要處理的數據時,或者一邊讀取一邊處理更加高效
時,咱們就須要用到數據流。NodeJS中經過各類Stream來提供對數據流的操
做。Stream基於事件機制工做,全部Stream的實例都繼承於NodeJS提供

1
2
3
4
5
6
7
var rs = fs.createReadStream(pathname);
             rs.on( 'data' , function (chunk) {
             doSomething(chunk);
});
     rs.on( 'end' , function () {
             cleanUp();
});
上邊的代碼中data事件會源源不斷地被觸發,無論doSomething函數是否處
理得過來。代碼能夠繼續作以下改造,以解決這個問題。
1
2  
3
4
5
6
7
8
9
10
var rs = fs.createReadStream(src);
            rs.on( 'data' , function (chunk) {
            rs.pause();
            doSomething(chunk, function () {
            rs.resume();
});
});
            rs.on( 'end' , function () {
            cleanUp();
});
此外,咱們也能夠爲數據目標建立一個只寫數據流,示例以下:
1
2
3
4
5
6
7
8
var rs = fs.createReadStream(src);
var ws = fs.createWriteStream(dst);
              rs.on( 'data' , function (chunk) {
              ws.write(chunk);
});
           rs.on( 'end' , function () {
              ws.end();
});

咱們把doSomething換成了往只寫數據流裏寫入數據後,以上代碼看起來就
像是一個文件拷貝程序了。可是以上代碼存在上邊提到的問題,若是寫入速度
跟不上讀取速度的話,只寫數據流內部的緩存會爆倉。咱們能夠根
.write方法的返回值來判斷傳入的數據是寫入目標了,仍是臨時放在了緩
存了,並根據drain事件來判斷何時只寫數據流已經將緩存中的數據寫入
目標,能夠傳入下一個待寫數據了。所以代碼能夠改造以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
var rs = fs.createReadStream(src);
var ws = fs.createWriteStream(dst);
rs.on( 'data' , function (chunk) {
if (ws.write(chunk) === false ) {
rs.pause();
}
});
rs.on( 'end' , function () {
ws.end();
});
ws.on( 'drain' , function () {
rs.resume();
});




簡單使用的node教程挺好的

https://github.com/alsotang/node-lessons


nodejs異步帶來的困擾也將破局,從callback到promise,從promise到generator,從generator到co,從co到async/await,不管如何generator/co和async/await會在2016年獲得很是大的推廣


目前這些的支持除了nodejs sdk和babel外,typescript也是一個比較好的選擇







相關文章
相關標籤/搜索