1. 程式人生 > >Node.js 事件驅動獲取資料

Node.js 事件驅動獲取資料

Nodejs的單執行緒非阻塞I/O事件驅動

在 Java、PHP 或者.net 等伺服器端語言中,會為每一個客戶端連線建立一個新的執行緒。 而每個執行緒需要耗費大約 2MB 記憶體。也就是說,理論上,一個 8GB 記憶體的伺服器可以同時 連線的最大使用者數為 4000 個左右。要讓 Web 應用程式支援更多的使用者,就需要增加伺服器 的數量,而 Web 應用程式的硬體成本當然就上升了。 Node.js 不為每個客戶連線建立一個新的執行緒,而僅僅使用一個執行緒。當有使用者連線了, 就觸發一個內部事件,通過非阻塞 I/O、事件驅動機制,讓 Node.js 程式巨集觀上也是並行的。 使用 Node.js,一個 8GB 記憶體的伺服器,可以同時處理超過4 萬用戶的連線。

Nodejs 回撥處理非同步

//錯誤的寫法:  
function getData (){ 
    // 模擬請求資料     
    var result=''; 
    setTimeout(function(){         
         result='這是請求到的資料'  
    },200);     
    return result; 
 }  
console.log( getData ()); /* 非同步導致請求不到資料 */ 
// 正確的處理非同步 : 
function getData (callback){
     // 模擬請求資料     
var result=''; setTimeout (function(){ result='這是請求到的資料'; callback(result); },200); } getData (function( data ){ console.log(data); });

Nodejs events 模組處理非同步

Node.js 有多個內建的事件,我們可以通過引入 events 模組,並通過例項化 EventEmitter 類來繫結和監聽事件。

/*

 Node.js 事件迴圈:

 Node.js 是單程序單執行緒應用程式,但是通過事件和回撥支援併發,所以效能非常高。
 Node.js 的每一個 API 都是非同步的,並作為一個獨立執行緒執行,使用非同步函式呼叫,並處理併發。

 Node.js 有多個內建的事件,我們可以通過引入 events 模組,並通過例項化 EventEmitter 類來繫結和監聽事件,

 如下例項:

* */
// 引入 events 模組 var events=require('events'); //console.log(events); var EventEmitter=new events.EventEmitter(); //廣播 和接收廣播 EventEmitter.on('to_mime',function(data){ console.log(data); }) //監聽to_parent的廣播 EventEmitter.on('to_parent',function(data){ //console.log('接收到了這個廣播事件'); console.log(data); EventEmitter.emit('to_mime','給mime傳送的資料') }) setTimeout(function(){ console.log('開始廣播...'); //廣播to_parent事件 EventEmitter.emit('to_parent','傳送的資料') },1000);

這裡寫圖片描述

我的上一篇博文:http://blog.csdn.net/cckevincyh/article/details/78637576
中讀取mime.json檔案,返回指定mime type,我們使用的是回撥來處理非同步。現在我們改造一下,通過events 模組來處理非同步。
我們現在測試下我們的程式碼:

var fs=require('fs');
var events=require('events');

var EventEmitter=new events.EventEmitter();


function getMime(){

    fs.readFile('mime.json',function(err,data){
        EventEmitter.emit('data',data)
    })

}

getMime();/*執行方法*/
//監聽廣播資料
EventEmitter.on('data',function(mime){

    console.log(mime.toString());
})

這裡寫圖片描述

好了,通過events 模組我們可以獲取到我們的資料了,現在我們開始改造我們的程式碼:

exports.getMime=function(fs,EventEmitter,extname){  /*獲取字尾名的方法*/

    fs.readFile('./mime.json',function(err,data){

        if(err){
            console.log('mime.json檔案不存在');
            return false;
        }
        //console.log(data.toString());

        var Mimes=JSON.parse(data.toString());

        var result= Mimes[extname] || 'text/html';

        EventEmitter.emit('to_mime',result);

    })


}

//引入http模組
var http=require('http');

//fs模組

var fs=require('fs');

//path模組
var path=require('path');  /*nodejs自帶的模組*/

//url模組

var url=require('url');


var events=require('events');

var EventEmitter=new events.EventEmitter();

var mimeModel=require('./model/getmimefromfile_events.js');
//引入副檔名的方法是在檔案裡面獲取到的。
//console.log(mimeModel.getMime('.css'));   //獲取檔案型別

http.createServer(function(req,res){



    //http://localhost:8001/news.html    /news.html
    //http://localhost:8001/index.html    /index.html

    //css/dmb.bottom.css

    //xxx.json?214214124

    var pathname=url.parse(req.url).pathname;

    console.log(pathname);

    if(pathname=='/'){
        pathname='/index.html'; /*預設載入的首頁*/
    }

    //獲取檔案的字尾名
    var extname=path.extname(pathname);

    if(pathname!='/favicon.ico'){  /*過濾請求favicon.ico*/
        //console.log(pathname);
        //檔案操作獲取 static下面的index.html

        fs.readFile('static/'+pathname,function(err,data){

            if(err){  /*沒有這個檔案*/

                console.log('404');

                fs.readFile('static/404.html',function(error,data404){
                    if(error){
                        console.log(error);
                    }
                    res.writeHead(404,{"Content-Type":"text/html;charset='utf-8'"});
                    res.write(data404);
                    res.end(); /*結束響應*/
                })

            }else{ /*返回這個檔案*/

                mimeModel.getMime(fs,EventEmitter,extname);  /*呼叫獲取資料的方法*/

                EventEmitter.on('to_mime',function(mime){

                    res.writeHead(200,{"Content-Type":""+mime+";charset='utf-8'"});
                    //res.write(data);
                    res.end(data); /*結束響應*/
                })


            }
        })

    }

}).listen(8002);

這裡寫圖片描述

這裡寫圖片描述

setMaxListeners():
在預設情況下,同一個指定的事件,最多可以繫結10個事件處理函式。當繫結數超出時,啟動nodejs時,會有相應的錯誤提示。也可以通過下面的方法修改:

EventEmitter.setMaxListeners (n)   
//給EventEmitter設定最大監聽
//引數1: n 數字型別,最大監聽數

相關推薦

Node.js 事件驅動獲取資料

Nodejs的單執行緒非阻塞I/O事件驅動 在 Java、PHP 或者.net 等伺服器端語言中,會為每一個客戶端連線建立一個新的執行緒。 而每個執行緒需要耗費大約 2MB 記憶體。也就是說,理論上,一個 8GB 記憶體的伺服器可以同時 連線的最大使用者數為

node.js 事件驅動

在傳統程式設計中,i/o操作和本地函式呼叫的處理方式相同:處理過程需要一直等待直到某個操作結束才能繼續下去,這種基於i/o操作的阻塞式程式設計模型繼承自早期的分時系統,在這類系統中,每一個程序都對應著一個使用者,這樣做的目的是使得使用者之間相互隔離。並且在這類系統中,使用者在決定下一個操作前,必須先

node.js零基礎詳細教程(4):node.js事件機制、node異步IO操作

nod server nbsp node i++ 兩個 con 錯誤 定時器 第四章 建議學習時間3小時 課程共10章 學習方式:詳細閱讀,並手動實現相關代碼 學習目標:此教程將教會大家 安裝Node、搭建服務器、express、mysql、mongodb、編寫後臺業務邏

Node.js 事件循環

並且 循環 用戶 綁定 sta pri 應用 tac 調用 Node.js 事件循環 Node.js 是單進程單線程應用程序,但是通過事件和回調支持並發,所以性能非常高。 Node.js 的每一個 API 都是異步的,並作為一個獨立線程運行,使用異步函數調用,並處理並發

Node.js事件

node med event req nod eve js事件 highlight nds const EventEmitter = require(‘events‘); class MyEmitter extends EventEmitter {} const mye

js事件獲取

hang 執行 鍵盤事件 方式 函數 監聽事件 false ini t對象 獲取元素樣式屬性 Method DES clientWidth 獲取元素寬度 clientHeight 獲取元素高度(內容+內邊距) document.body.clientW

Edit on GitHub Node.js 事件迴圈,定時器和 process.nextTick()

Node.js 事件迴圈,定時器和 process.nextTick() 什麼是事件輪詢 事件迴圈是 Node.js 處理非阻塞 I/O 操作的機制——儘管 JavaScript 是單執行緒處理的——當有可能的時候,它們會把操作轉移到系統核心中去。 既然目前大多數核心都是多執行

js跨域獲取資料

目錄   一、通過jsonp跨域 2、通過修改document.domain來跨子域 3、使用window.name來進行跨域 4、使用HTML5中新引進的window.postMessage方法來跨域傳送資料 一、通過jsonp跨域 在js中,我們直接用X

node.js事件監聽

新增自定義監聽事件。 上述為建立自定義監聽,而node.js中多數模組已此為父類繼承監聽事件能力,下面看fs的stream中使用監聽: 1、data 當有資料可讀時觸發(只有readstream才能使用) 2、end 當沒有資料可讀時觸發(也是隻用於讀) 3、error 當讀寫

day32Struts2Day02(屬性和模型驅動獲取資料 攔截器定義配置和使用 攔截未登入使用者)

回顧 1、Struts2框架的概述,前端控制器的模式,核心的過濾器 2、入門 編寫 struts.xml配置檔案 3、配置檔案 配置檔案的載入 4、Action類的編寫和訪問 在Struts2框架中使用Servlet的API 1、在Action類中也可以獲取到Servlet一些常用的API

Nuxt.js asyncData方法獲取資料(await axios和 axios區別)

在專案中需要在初始化頁面前先得到資料,也就是我們常說的非同步請求資料。Nuxt.js貼心的為我們擴充套件了Vue.js的方法,增加了asyncData(){……}。從名字上就很好理解,這是一個非同步的方法。 建立遠端資料 在這裡製作一些假的遠端資料,我選擇的網站是myjson.com,它是一

node.js事件events詳解

nodejs基於事件驅動 事件釋出,事件訂閱 大多數 Node.js 核心 API 構建於慣用的非同步事件驅動架構,其中某些型別的物件(又稱觸發器,Emitter)會觸發命名事件來呼叫函式(又稱監聽器,Listener)。同步函式,非同步觸發,通過回撥函式處理

Node.js中,獲取req請求的原始IP

headers = {"x-real-ip":"127.0.0.1","x-forwarded-for":"127.0.0.1","host":"127.0.0.1","connection":"close","k2":"v2","k1":"v1","cache-control":"no-cache","

Vue.js--基於$.ajax獲取資料並與元件的data繫結

Vue.js與jQuery不衝突??? 在實際的應用中,幾乎90%的資料是來源於服務端的,前端和服務端之間的資料互動一般是通過ajax請求來完成的。 說到ajax請求,第一反應肯定想到了jQuery

Nuxt.js anyncData方法獲取資料

在專案中需要在初始化頁面前先得到資料,也就是我們常說的非同步請求資料。Nuxt.js貼心的為我們擴充套件了Vue.js的方法,增加了anyncData。從名字上就很好理解,這是一個非同步的方法。 建立遠端資料 在這裡製作一些假的遠端資料,我選擇的網站是myjson.com,它是一個js

JS從後臺獲取資料,前臺動態新增tr標籤中的td標籤

功能描述: 要求從後臺查詢該省份的所有城市,然後動態的再前臺固定的tr標籤中新增相應的td標籤來展示城市基本資訊; 一、前臺jsp及js原始碼 jsp:在固定的tr標籤中新增一個

Acticle 23:有關瀏覽器中使用js跨域獲取資料的描述

題目如下: 下面有關瀏覽器中使用js跨域獲取資料的描述,說法錯誤的是? A.域名、埠相同,協議不同,屬於相同的域 B.js可以使用jsonp進行跨域 C.通過修改document.domain來跨子域 D.使用window.name來進行跨域 答案:

【JavaScript】從事件驅動資料驅動

批處理   在多年以前,計算機程式通常是以批處理的模式執行。所謂批處理,就是開發者事先寫好一些程式碼,再將這些程式碼一次執行。這種處理方式有點類似於通過HTML程式碼直接編寫的網頁。瀏覽器只是將HTM

node.js中通過dgram資料報模組建立UDP伺服器和客戶端

node.js中 dgram 模組提供了udp資料包的socket實現,可以方便的建立udp伺服器和客戶端。   一、建立UDP伺服器和客戶端 服務端: const dgram = require('dgram'); //建立upd套接字 //引數一表示套接字型別,'udp4'

Node.js中怎麼獲取北京時間?

基於Node.js開發開發的時候,呼叫new Date()出來的時間是這樣的: 2017-01-18T09:30:38.405Z 而當前時間北京時間是17:30,為了不讓自己總有穿越感,於是需要轉換一下。 過程可以是這樣的(在Node.js的命令列下): > a