摘要:一個匿名函數,執行,事件全部完成,執行最后一句,程序執行完畢。這個事件的監聽器為一個匿名函數,事件名稱為,當秒以后被觸發先對象發送一個事件觸發了匿名函數即監聽器,監聽器被執行。
node.js事件循環
node.js單進程,單線程的程序
每一個api都支持回調
所有的事件機制都是設計模式中的
一共是23種設計模式事件驅動程序
http://design-patterns.readth...
一個對象發生改變的時候,將自動通知其他對象,其他對象將相應的做出反應。發生改變的對象為觀察目標,被通知的對象為觀察者。一個觀察目標可以對應多個觀察者,而這些觀察者之間沒有任何聯系,可以根據需要增加觀察者,使得系統更加容易擴展,依賴關系為一對多,又被稱為模型-視圖模式
web server接收到請求,將其關閉,進行處理,然后接著服務下一個web請求。
當請求完成以后,放回處理隊列,當到達隊列開頭的時候,將其結果返回給用戶
即非阻塞式I/O 事件驅動I/O
會有一個主循環來監聽事件,當檢測到事件以后,觸發回調函數
PS C:UsersmingmDesktop est> node main.js 連接成功 數據接收成功 程序執行完畢 PS C:UsersmingmDesktop est>
// 引入一個 events 模塊 var events = require("events"); // 創建 eventEmitter對象 var eventEmitter = new events.EventEmitter(); // 創建connection事件的處理程序 var connectHandLer = function connected() { console.log("連接成功"); // 觸發 data_received 事件 eventEmitter.emit("data_received"); }; // 綁定cinnection事件處理程序 eventEmitter.on("connection", connectHandLer); // 綁定data_received事件,并完成處理程序的書寫 eventEmitter.on( "data_received", function() { console.log("數據接收成功"); } ); // 觸發 connection 事件 eventEmitter.emit("connection"); console.log("程序執行完畢");
程序的執行過程,先完成各種綁定,觸發connection事件以后,尋找綁定的處理程序,為connected(),然后,執行一半,又被觸發,data_received事件。尋找綁定的處理程序。一個匿名函數,執行,事件全部完成,執行最后一句,程序執行完畢。
多用戶執行的情況下,觸發事件以后,若處理程序正被其他用戶占用,排隊,直到前方全部處理完成以后,接著該用戶使用處理程序進行處理。
node所有的異步I/O操作在完成的時候都會發送到一個事件到達事件隊列。node里的對象能夠分發事件
產生的事件的對象都是events.EventEmitter的實例
events模塊提供一個對象,它是對事件的觸發和事件的監聽的封裝
PS C:UsersmingmDesktop est> node main.js 事件觸發 PS C:UsersmingmDesktop est>
過五秒后響應
// event.js文件 var EventEmitter = require("events").EventEmitter; var event = new EventEmitter(); // 創建一個event對象 event.on("some_event", function(){console.log("事件觸發");}); setTimeout(function(){event.emit("some_event");}, 5000);
大概解釋一下這段代碼
前兩句很簡單,后兩句說一下,event的對象注冊了一個事件的監聽器。這個事件的監聽器為一個匿名函數,事件名稱為some_event,當5000秒以后被觸發先對象event發送一個事件some_event觸發了匿名函數即監聽器,監聽器被執行。
其中EventEmitter的每個事件由一個事件名和若干參數組成,對于一個事件能有若干的監聽器,當事件觸發的時候,監聽器會被依次調用,事件參數作為回調函數的參數進行傳遞,需要注意的是,監聽器會被依次調用
error是一個多帶帶列出來的事件,一般要為其綁定一個監聽器,因為node如果拋出error,若沒有監聽器執行,將會直接退出執行,并返回錯誤
Buffer緩沖區處理TCP或者文件流的時候,需要用到二進制的數據,定義了一個Buffer類,該類用于專門存放二進制數據的緩沖區
Buffer與字符編碼const buf = Buffer.from("ming", "ascii"); // 聲明一個只讀的變量 console.log(buf.toString("hex")); console.log(buf.toString("utf-8"));
PS C:UsersmingmDesktop est> node main.js 6d696e67 ming PS C:UsersmingmDesktop est>創建一個buffer類,并完成讀取寫入
PS C:UsersmingmDesktop est> node main.js 23456789:;<=>?@ABCDEFGHIJK 23456789:;<=>?@ABCDEFGHIJK PS C:UsersmingmDesktop est>
buf = Buffer.alloc(26); for(var i = 0; i < 26; i++){ buf[i] = 50 + i; }; console.log(buf.toString("ascii")); console.log(buf.toString("utf8"));將buffer轉換為jsoon
PS C:UsersmingmDesktop est> node main.js {"type":"Buffer","data":[1,2,3,4,5]} PS C:UsersmingmDesktop est>
const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]); const json = JSON.stringify(buf); console.log(json);將JSON轉換為Buffer 一個轉換方法JSON.parse
> JSON.parse("{"1": 3, "2": [4, 5, 6]}", function (k, v) { ... console.log(k); // 輸出當前的屬性名,從而得知遍歷順序是從內向外的, ... console.log("----------"); // 最后一個屬性名會是個空字符串。 ... console.log(v); ... }); 1 ---------- 3 0 ---------- 4 1 ---------- 5 2 ---------- 6 2 ---------- [ <3 empty items> ] ---------- {} undefined >開始轉換
const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]); const json = JSON.stringify(buf); console.log(json); const copy = JSON.parse( // 調用JSON.parse函數,將字符串轉換為對象,后一個參數為轉換的函數,轉換的時候將會調用 json, (key, value) => { // 此為es6的語法,一個匿名函數 console.log(value, "----", !!value, "----", value.type, "-----", value.data); return value && value.type === "Buffer" ? Buffer.from(value.data): value; // 只留下最后一個進行轉換,前面的轉換全部被覆蓋 } ) // 輸出:console.log(copy);
PS C:UsersmingmDesktop est> node main.js {"type":"Buffer","data":[1,2,3,4,5]} Buffer ---- true ---- undefined ----- undefined 1 "----" true "----" undefined "-----" undefined 2 "----" true "----" undefined "-----" undefined 3 "----" true "----" undefined "-----" undefined 4 "----" true "----" undefined "-----" undefined 5 "----" true "----" undefined "-----" undefined [ 1, 2, 3, 4, 5 ] "----" true "----" undefined "-----" undefined { type: "Buffer", data: [ 1, 2, 3, 4, 5 ] } "----" true "----" "Buffer" "-----" [ 1, 2, 3, 4, 5 ]Buffer的合并PS C:UsersmingmDesktop est>
var buffer1 = Buffer.from("222"); var buffer2 = Buffer.from("3333"); var buffer3 = Buffer.concat([buffer1, buffer2]); console.log(buffer3.toString());Stream流
流為一個抽象的接口,
從流中讀取數據PS C:UsersmingmDesktop est> node main.js end! 33333333333333333333333333 PS C:UsersmingmDesktop est>
var fs = require("fs"); var data = ""; // 創建可讀流 var readerStream = fs.createReadStream("input.txt"); // 設置編碼為 utf8 readerStream.setEncoding("UTF8"); // 處理流事件 data事件 readerStream.on("data", (chunk) => {data += chunk;}); // 遇到數據讀取,將讀取到的內容賦值給data // 處理流事件 end事件 readerStream.on("end", () => {console.log(data);}); // 將讀取到的保存到內存中的數據打印出來 // 處理事件 error readerStream.on("error", (err) => {console.log(err.stack);}); // 處理error事件,將錯誤輸出,避免程序的運行中斷 console.log("end!");寫入流
PS C:UsersmingmDesktop est> node main.js 程序執行完畢 寫入完成 PS C:UsersmingmDesktop est>
var fs = require("fs"); var data = "這是一段示例"; // 創建一個可以寫入的流,寫入到文件output.txt中 var writerStream = fs.createWriteStream("output.txt"); // 使用 utf8 編碼寫入數據 writerStream.write(data, "UTF8"); // 標記文件末尾 writerStream.end(); // 處理流事件 --> data, end, add error writerStream.on("finish", () => {console.log("寫入完成");}); writerStream.on("error", () => {console.log(err.stack);}); console.log("程序執行完畢");管道流
把兩個文件之間建立流,讓一個文件的數據流向另外一個文件
PS C:UsersmingmDesktop est> node main.js 程序執行完畢 PS C:UsersmingmDesktop est>
var fs = require("fs"); // 創建一個可讀流 var readerStream = fs.createReadStream("input.txt"); // 創建一個可寫流 var writerStream = fs.createWriteStream("output.txt"); // 管道讀寫操作 // 將兩個流通過管道連接起來 readerStream.pipe(writerStream); console.log("程序執行完畢");
這里需要注意的是,由于流的影響,導致在操作的時候,會覆蓋掉要寫入文件的內容,原先的內容會被覆蓋
鏈式流PS C:UsersmingmDesktop est> node main.js 文件壓縮完成 PS C:UsersmingmDesktop est>
var fs = require("fs"); var zlib = require("zlib"); // 壓縮 input.txt文件為 input.txt.gz fs.createReadStream("input.txt") // 創建一個可讀流 .pipe(zlib.createGzip()) // 將創建的可寫流和壓縮流連接 .pipe(fs.createWriteStream("input.txt.gz")); // 在創建可寫流,將三個流連接到一起 console.log("文件壓縮完成");內容未被覆蓋的寫入
var fs = require("fs"); var read = fs.createReadStream("output.txt"); var write = fs.createWriteStream("input.txt"); read.pipe(write); console.log("執行完畢");
具體詳細,請查文檔
https://nodejs.org/api/fs.htm...
https://nodejs.org/api/fs.htm...
文檔寫的很詳細,后面的參數為一個對象,通過對象即可進行修改
模塊之前已經闡述過一部分,這里闡述服務器端的模塊
服務器端的模塊node中自帶了一個http模塊,在代碼中請求他,并將返回值賦值給本地變量。即本地變量變成了一個擁有所有http模塊所提供的公共方法的對象。
node中有四個模塊,(原生模塊和三種文件模塊)
原生模塊和文件模塊優先級不同,都會優先從文件模塊的緩存中加載以及存在的模塊
從原生模塊加載原生模塊的優先級低于文件模塊緩存的優先級。原生模塊也有緩存區
從文件加載這個上一篇以及闡述完成,不在闡述
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/96281.html
摘要:表示當前正在執行的腳本的文件名。默認編碼為模式為,為回調函數,回調函數只包含錯誤信息參數,在寫入失敗時返回。參數使用說明如下通過方法返回的文件描述符。 Node.js回調 Node.js異步編程的直接體現就是回調。 阻塞代碼: const fs = require(fs); let data = fs.readFileSync(input.txt); console.log(data...
摘要:端輸入數據到端,對就是輸入流,得到的對象就是可讀流對就是輸出端得到的對象是可寫流。在中,這四種流都是的實例,它們都有事件,可讀流具有監聽數據到來的事件等,可寫流則具有監聽數據已傳給低層系統的事件等,和都同時實現了和的事件和接口。 原文地址在我的博客 node中的Buffer和Stream會給剛接觸Node的前端工程師們帶來困惑,原因是前端并沒有類似概念(or 有我們也沒意識到)。然而,...
摘要:創建簡單應用使用指令來載入模塊創建服務器使用方法創建服務器,并使用方法綁定端口。全局安裝將安裝包放在下。的核心就是事件觸發與事件監聽器功能的封裝。通常我們用于從一個流中獲取數據并將數據傳遞到另外一個流中。壓縮文件為文件壓縮完成。 創建簡單應用 使用 require 指令來載入 http 模塊 var http = require(http); 創建服務器 使用 http.create...
摘要:簡介項目命名為就是一個服務器單純開發一個服務器的想法,變成構建網絡應用的一個基本框架發展為一個強制不共享任何資源的單線程,單進程系統。單線程弱點無法利用多核錯誤會引起整個應用退出,應用的健壯性大量計算占用導致無法繼續調用異步。 NodeJs簡介 Ryan Dahl項目命名為:web.js 就是一個Web服務器.單純開發一個Web服務器的想法,變成構建網絡應用的一個基本框架.Node發展...
摘要:這使我們的知道什么時候原始模塊被初始化,在初始化后執行預初始化隊列的操作,之后清空預初始化隊列,再調用作為參數的回調函數,以下為具體步驟把賦值給,表示預初始化已經完成了。 本系列文章為《Node.js Design Patterns Second Edition》的原文翻譯和讀書筆記,在GitHub連載更新,同步翻譯版鏈接。 歡迎關注我的專欄,之后的博文將在專欄同步: Encount...
閱讀 1523·2023-04-26 02:03
閱讀 4707·2021-11-22 13:53
閱讀 4579·2021-09-09 11:40
閱讀 3782·2021-09-09 09:34
閱讀 2125·2019-08-30 13:18
閱讀 3501·2019-08-30 11:25
閱讀 3295·2019-08-26 14:06
閱讀 2545·2019-08-26 13:52