node學習筆記

1、準備(github地址)

什麼是Javascript?

  • ...

Javascript能作什麼?

  • .....

瀏覽器中的Javascript能夠作什麼?

  • 操做DOM(增刪改查)
  • AJAX/跨域
  • BOM
  • ECMAScript

瀏覽器中的Javascript不能作什麼?

  • 文件操做
  • 沒有辦法操做系統信息
  • 因爲運行環境
編程語言的能力取決於?
  • 語言自己只是提供了定義變量、定義函數、定義類型、流程控制、循環結構之類的操做
  • 取決於運行該語言的平臺(環境)
  • 對於js來講,常常說的JS實際是ES,大部分能力都是由瀏覽器的執行殷勤決定
  • BOM和DOM能夠說是瀏覽器開放出來的接口
  • 好比:Cordova中提供JS調用攝像頭,操做本地文件的API
  • Java既是語言也是平臺
  • Java運行在Java虛擬機(跨操做系統)
  • PHP是語言也是平臺
  • C#語言,平臺:.net framework
  • C#能夠運行在MONO這樣的平臺
  • 由於有人須要將C#運行在Linux平臺,因此出現了MONO
Javascript只能夠運行在瀏覽器中嗎?
  • 不是
  • 能運行在哪裏,取決於這個環境有沒有特定的平臺

node是什麼?(Ryan Dahl)

  • Node是javascript運行於服務端的運行環境
  • 注意:是Node選擇了Javascript,不是Javascript發展出來一個Node ###Node的誕生
  • 2008年左右,隨着AJAX的普及,WEB走向複雜化、系統化
  • 2009年2月Ryan Dahl想要建立一個輕量級,適應現代WEB開的平臺
  • 2009年5月Ryan Dahl在GitHub中開源了最第一版本,同年11月的JSConf就安排了NODE講座
  • 2010年末Joyent公司資助,Ryan Dahl也加入了改公司,專門負責NODE的開發
  • 2011年7月在微軟的支持下登陸Windows平臺

Node在web中的用途

  • node開發的Application處理用戶的全部請求和給用戶的響應
  • 分發數據(調用NODE服務器接口,再去調用傳統服務器)請求,渲染HTML頁面

總結:Node是Javascript的運行環境(平臺),不是一門語言,也不是Javascript的框架。javascript

環境配置

  • 下載安裝包
  • 安裝過程

makdir .net->建立一個資源管理器不能建立的一些文件 node --use_strict->必須是嚴格模式css

匿名函數自執行的方式:
  • (function(){console.log(1)})()
  • +function(){console.log(1)}()
  • !function(){console.log(1)}()

全局對象

  • global(等價於客戶端javascript的window對象)
  • process.stdin->標準輸入(採集用戶的輸入)
  • process.stdout.write()->標準輸出相似console.log();
模板字符串``中間能夠隨意換行
  • var msg='hello';
  • var a=1;
  • process.stdout.write(${msg} world);
  • process.stdout.write(${msg} world ${a});

Debug

  • vs code編輯器裏面能夠調試
  • node debug XXX.js能夠調試
  • node-inspector執行後打開127.0.0.1:8080頁面調試(如:node-debug d.js此時會自動打開瀏覽器調試界面google)
  • devtool XXX.js也是調試有BUG

練習

  • ctrl+c終止當前進程
  • 簡單的人際交互,如何在控制檯接收用戶的輸入,如:e.js

異步操做

  • 現實
  • 程序>一、setTimeout();二、$.ajax()

node中的異步操做

  • Node採用Chrome V8引擎處理Javascript腳本,V8最大的特色就是單線程運行,一次只執行一個任務。
  • Node大量採用異步操做(asynchronous operation),即任務不是立刻執行,而是插在任務隊列的尾部,等到前面的任務運行完成後再執行
  • 提升代碼的影響能力

什麼是I/O

  • I/O【input/output】
  • 能夠理解爲從輸入到輸出之間的轉化過程
  • 好比:敲鍵盤(輸入),看到編輯器出現字符(輸出)
  • 移動鼠標(輸入),看到光標移動(輸出)

回調函數的設計

  • 對於一個函數若是須要定義一個回調函數:
    • 回調函數的必定做爲參數的最後一個參數出現:一、function getFile(name,job,callback){}
    • 回調函數的第一個參數默認接收錯誤信息,第二個參數纔是真正的回調數據(便於外界獲取調用的錯誤狀況);如:getFile('jason','coding',function(error,data){if(error) throw error;console.log(data);});
  • Node統一約定
    • 強調錯誤優先,由於以後的操做大部分都是異步方式,沒法經過try catch捕獲異常,因此錯誤優先的回調函數第一個參數爲上一步的錯誤信息
非阻塞I/O-->其實就是Node的核心特性

事件驅動和非阻塞機制

  • Node平臺將一個任務連同該任務的回調函數放到一個事件循環系統中
  • 事件循環高效的管理系統池同時高效執行每個任務
  • 當任務執行完成事後自動諮詢回調函數

非阻塞的優點

  • 提升代碼的響應效率
  • 充分利用單核CPU的優點
  • 改善I/O的不可預測帶來的問題
  • 如何提升一我的的工做效率
  • 可是:目前大多數都是多核CUP

異步回調的問題(相對於傳統的代碼)

  • 異步事件驅動的代碼
  • 不易閱讀
  • 不易調試
  • 不易維護

進程和線程

一、進程(XXX.exe)
  • 每個正在運行的應用程序稱之爲進程
  • 每個應用程序至少有一個進程
  • 進程是用來給應用程序提供一個運行環境
  • 進程是操做系統爲應用程序分配資源的一個單位
二、線程
  • 用來執行應用程序中的代碼
  • 在一個進程內部,能夠有多個線程
  • 在一個線程內部,同事只能作一件事
  • 並且傳統的開發方式大部分都是I/O阻塞的
  • 因此須要多線程來更好的利用硬件資源
  • 給人一種錯覺:線程越多越好

2、模塊化結構

  • Node實現的CommonJS規範,因此可使用模塊化的方式組織代碼結構
  • Node採用的模塊化結果是按照CommonJS規範
  • 模塊與文件是一一對應關係,即加載一個模塊,實際上就是加載對應的一個模塊文件

CommonJS規範概述

CommonJS模塊的特色

  • 全部代碼都運行在模塊做用域,不會污染全局做用域
  • 模塊能夠屢次加載,可是隻會在第一次加載時運行一次,而後運行結果就被緩存了,之後再加載,就直接讀取緩存結果,要想讓模塊再次運行,必須清除緩存
  • 模塊加載的順序,按照其在代碼中出現的順序

module對象

  • Node內部提供一個Module構建函數,全部模塊都是Module的實例,屬性以下:
    • module.id模塊的識別符,一般是帶有絕對路徑的模塊文件名
    • module.filename模塊定義的文件的絕對路徑
    • module.loaded返回一個布爾值,表示模塊是否已經完成加載
    • module.parent返回一個對象,表示調用該模塊的模塊
    • module.children返回一個數組,表示該模塊要用到的其餘模塊
    • module.exports表示模塊對外輸出的值!
  • 載入一個模塊就是構建一個Module實例

模塊的定義

  • 一個新的JS文件就是一個模塊
  • 一個合格的模塊應該是有導出成員的,不然模塊就失去了第一的意義
  • 模塊內部是一個獨立(封閉)的做用域,模塊之間不會衝突
  • 模塊之間必須經過導出導入的方式協同
  • 導出方式:
    • exports.name=value;
    • module.exports={name:value};
  • 此時就不必在模塊內部寫自執行函數了!!
  • module.exports和exports
  • module.exports是用於爲模塊導出成員的接口
  • exports是指向module.exports的別名,至關於在模塊開始的時候執行:var exports=module.exports;
  • 一旦爲module.exports賦值,就會切斷以前二者的相關性
  • 最終模塊的導出成員以module.exports爲準

模塊的分類

  • 文件模塊:就是咱們本身寫的功能模塊文件
  • 核心模塊:Node平臺自帶的一套基本的功能模塊,也有人稱之爲Node平臺的API
  • 第三方模塊:社區或第三方我的開發好的功能模塊,能夠直接拿來用

模塊化開發的流程

  • 建立模塊:new some.js
  • 導出成員:module.exports={}
  • 載入模塊:var some=require('./some.js');
  • 使用模塊:some.add(1,2);

模塊內全局環境(僞)

  • 咱們以後的文件操做中必須使用絕對路徑
  • __dirname:用於獲取當前文件所在目錄的完整路徑,在REPL環境無效
  • __filename:用來獲取當前文件的完整路徑,在REPL環境一樣無效
  • module:模塊對象
  • exports:映射到module.exports的別名
  • require():require.cache、require.extensions、require.main、require.resolve()

練習:命令行下的計算器,c.js和e.js

  • c.js裏是非模塊化的
  • e.js是模塊化的(CommonJS規範)
  • module.exports={a,b,c};ES6的'自動屬性'

模塊的載入:require函數簡介

  • node使用CommonJS模塊規範,內置的require函數用於加載模塊的文件
  • require的基本功能是:讀取並執行一個javascript文件,而後返回該模塊的exports對象
  • 若是沒有發現指定的模塊會報錯!

require擴展名:規則>描述的越詳細越準確,相似CSS的選擇器優先級

  • require加載文件時能夠省略擴展名:require('./module1')
    • 此時會默認先找require('./module1.js');
    • 若是默認的.js文件不存在接下來會繼續默認找require('./module1.json');

加載文件規則

  • 經過"./"或"../"開頭:則按照相對路徑熊當前文件所在文件夾開始尋找模塊:require('../xxx.js')>上級目錄下找xxx.js文件;
  • 經過/開頭:則以系統根目錄開始尋找模塊:require('/Users/xxx/Documents/sss.js')>以絕對路徑的方式找,無心義!;
  • 若是參數字符串不以"./"或者"/"開始,則表示加載的是一個默認提供的核心模塊(位於Node的系統安裝目錄中):require('fs')、require('http')、require('path')等等;
  • 或者從當前目錄向上搜索node_modules目錄中的文件:require('my_module')>各級node_modules夾中搜索my_nodule.js文件;
  • 若是require傳入的是一個目錄的路徑,會自動查看該目錄的package.json文件,而後加載main字段指定的入口文件
  • 若是package.json文件沒有main字段,或者根本就沒有package.json文件,則默認找目錄下的index.js文件做爲模塊:require('./filesModule')>當前目錄下找filesModule目錄中的index.js文件;

注意require('filename'):

  • 加載的模塊名字若是跟系統的模塊衝突,系統的優先級最高!
  • 就近原則去找node_modules文件夾下的filename文件

require的實現機制:自定義的的$require,g.js和模塊module2.js

  • 將傳入的模塊的ID經過加載規則找到對應的模塊文件
  • 讀取這個文件裏面的代碼
  • 經過拼接的方式爲該段代碼構建私有空間
  • 執行該代碼
  • 拿到module.exports返回

__dirname與__filename:如f.js

  • __dirname當前文件所在目錄的完整路徑
  • __filename當前文件的完整路徑 ###思考與練習:
  • 一、如何定義和導入模塊?
  • 二、如何使用模塊化的方式組織代碼結構?
  • 三、載入模塊的規則
  • 四、瞭解模塊的加載機制
  • 五、自定義一個$require相似require,如$require下面的:index.js

模塊的緩存:如h.js

  • 第一次加載某個模塊時,Node會緩存該模塊,之後再加載該模塊就直接從緩存取出該模塊的module.exports屬性(不會再次執行該模塊);
  • 若是須要屢次執行模塊中的代碼,通常可讓模塊暴露行爲(函數)
  • 模塊的緩存能夠經過require.cache拿到,一樣也能夠刪除

緩存是如何實現(如:i.js)

如何刪除緩存(如:i.js),通常不會刪除緩存

  • 緩存require.cache ##

3、Node:核心模塊、文件操做、文件流、網絡操做

一、核心模塊

  • 核心模塊的意義:html

    • 若是隻是在服務器運行javascript代碼,意義不大,由於沒法實現任何功能(讀寫文件,訪問網絡)
    • Node的用處在於它自己還提供的一系列功能模塊,用於操做系統運動
    • 這些核心的功能模塊在Node中的內置
  • 內置的有以下模塊java

    • path:處理文件路徑
    • fs:操做文件系統
    • child_process:新建子進程
    • util:提供一些列實用的小工具
    • http:提供HTTP服務器功能
    • url:用於解析URL
    • querystring:解析URL中的查詢字符串
    • crypto:提供加密和解密功能(MD5是不可逆,沒法解密!!)
    • 其餘

Node Package

因爲Node是一套輕內核的平臺,雖然提供了一系列的內置模塊,可是不足以知足開發者的需求,因而出現了包(Package)的概念。與核心模塊相似,就是講一些預先設計好的功能或者API封裝到一個文件夾,提供給開發者使用node

1):包的加載機制
  • 與內置模塊相同,一樣使用require方法,如:const express=require('express');
  • 加載機制也和內置模塊加載機制相同
  • 加載注意事項:
    • 先在系統核心(優先級最高)的模塊中找
    • 而後再到當前項目中的:node_mocules目錄中去找
2):如何管理好本身的包
  • 因爲Node自己並無太多的功能性API。因此市面上涌現出大量的第三方人員開發出來的Package
  • 包的生態圈一旦繁榮起來,就必須有工具去代替人腦或者文檔的方式去管理
  • 此時NPM誕生了~

NPM(Node Package Manager)

  • 隨着時間的發展,NPM出現了兩層概念:
    • 一層韓式是Node的開放式模塊登記和管理系統,也能夠說是一個生態圈,一個社區
    • 另外一層含義是Node默認的模塊管理器,是一個命令行下的軟件,用來安裝和管理Node模塊
  • 官方地址:https://www.npmjs.com/
  • 國內加速鏡像地址:https://npm.taobao.org/
1):安裝NPM
  • NPM不須要單獨安裝,默認在安裝Node的時候會自動一塊兒安裝NPM
  • 可是Node附帶的NPM可能不是最新版本,最好用下面的命令更新到最新版本:$ npm install npm -g
  • 默認安裝到當前系統Node所在的目錄下
  • 因爲以前使用NVM的方式安裝的Node因此須要從新配置NPM全局目錄
2):配置NPM的全局目錄?
  • npm config set prefix [filepath]
  • 將NPM目錄配置到其餘目錄時,必須將該目錄放到環境變量中,不然沒法在全局使用
3):NPM經常使用命令->https://docs.npmjs.com/
  • npm config [ls|list|set|get] [name] [value]
  • npm init [--yes|-y]
  • npm search [name]
  • npm info [name]
  • npm install [--global|-g] [name]
  • npm uninstall [--global|-g] [name]
  • npm list [--global|-g]
  • npm outdated [--global|-g]
  • npm update [--global|-g] [name]
  • npm run [task]
  • npm cache [clean]

二、文件操做(important)

Node內核提供了不少與文件操做相關的模塊,每一個模塊都提供了一些最基本的操做API,在NPM中也有社區提供的功能包git

fs:
  • 基礎的文件操做API ######path:
  • 提供和路徑相關的操做API ######readline:
  • 用於讀取大文本文件,一行一行讀 ######fs-extra:(第三方)
  • https://www.npmjs.com/package/fs-extra

1):同步或者異步調用(如:day03/code/02.js)

  • fs模塊對文件的幾乎全部操做都有同步和異步兩種形式
    • readFile()
    • readFileSync()
  • 區別:
    • 同步調用會阻塞代碼的執行,異步則不會
    • 異步調用會將讀取任務下達到任務隊列,直到任務執行完成纔會回調
    • 異常處理方面,同步必須使用 try catch 方式,異步能夠經過回調函數的第一個參數
    • 同步比異步更加耗費時間

2):路徑模塊

在文件操做中,都必須使用物理路徑(絕對路徑),path模塊提供了一些列與路徑相關的APIgithub

3):什麼是緩衝區

  • 緩衝區就是內存中操做數據的容器
  • 只是數據的容器而已
  • 經過緩衝區能夠很方便的操做二進制數據
  • 並且在大文件操做時必須有緩衝區
若是讀取文件沒有指定編碼的話,默認讀取的是一個Buffer(緩衝區)
  • Buffer的做用,對我們目前的狀況來講只不多使用場景
    • 將圖片轉成BASE64編碼(code/04.js)
    • 對文字進行BASE64編碼

4):爲什麼要有緩衝區

  • JS是比較擅長處理字符串,可是早起的應用場景主要用於處理HTML文檔,不會有太大批次的數據處理,也不會接觸到二進制的數據
  • 而在Node中操做數據、網絡通訊是沒辦法徹底以字符串的方式操做的
  • 因此在Node中引入了一個二進制的緩衝區的實現:Buffer
  • buf.toString([encoding[, start[, end]]])這裏也能夠設置編碼:如code/03.js
相關文章
相關標籤/搜索