Nodejs的非阻塞IO、異步以及 事件驅動EventEmitter解決異步 (7)

1Nodejs 的單線程 非阻塞 I/O 事件驅動   

Node.js 不爲每一個客戶鏈接建立一個新的線程, 而僅僅使用一個線程。當有用戶鏈接了,
就觸發一個內部事件,經過非阻塞 I/O、事件驅動機制,讓 Node.js 程序宏觀上也是並行的。
使用 Node.js,一個 8GB 內存的服務器,能夠同時處理超過 4 萬用戶的鏈接

html

2 異步IO執行過程node

console.log('1');

// fs.readFile 是非阻塞IO
fs.readFile('mime.js',function (err,data) {
    console.log('2');
});

console.log('3');

 

執行結果json

 

 

 

2異步存在的問題

// 錯誤寫法

// 非阻塞io 引起的問題
function getMime() {
    console.log('1'); // 1
    fs.readFile('mime.json',function(err,data){
        console.log('2');  // 2
        return data.toString();
    });
    console.log('3'); // 3
}

console.log(getMime()); // undefined

 

執行結果,獲取不到文件內容api

 

3 回調解決異步問題

// 正確寫法
var fs = require('fs');
// 回調 callback
function getMime(callback) {
    fs.readFile('mime.json',function(err,data){
        callback(data); //使用回調傳值
    });
}

getMime(function (result) {
    console.log(result.toString()); // 回調過程當中獲取值
}); // 執行函數

 

 

4  事件驅動

1. nodejs 事件循環:服務器

  nodejs 是單進程單線程應用程序,可是經過事件和回調支持併發,因此性能很是高;併發

  nodejs 的每一份api都是異步的,並做爲一個獨立線程運行,使用一步函數調用,並處理併發;app

  nodejs 有多個內置的事件,咱們能夠經過引入 events 模塊,並實例化 EventEmitter 類來綁定和監聽事件.異步

 

// 引入 events 模塊

var events=require('events');

//console.log(events);

// 實例 EventEmitter 監聽和廣播 事件對象
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','給to_parent發送的數據')

},1000);

 

 

 

執行結果函數

 

 

 

5 使用事件驅動解決異步問題

 

var fs = require('fs');
var events = require('events');
var EventEmitter = new events.EventEmitter();

function getMime() {
    fs.readFile('mime.json',function(err,data){
        EventEmitter.emit('mime',data) // 事件傳值
    });
}

getMime(); //執行函數

// 監聽 mime 事件
EventEmitter.on('mime',function (data) {
    console.log(data.toString());
});

 

6 get 和post 請求

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

var url=require('url');

var ejs=require('ejs');

var fs=require('fs');

//路由:指的就是針對不一樣請求的 URL,處理不一樣的業務邏輯。
http.createServer(function(req,res){
    res.writeHead(200,{"Content-Type":"text/html;charset='utf-8'"});

    //獲取get 仍是post請求
    var method=req.method.toLowerCase();
    //console.log(method);
    var pathname=url.parse(req.url,true).pathname;

    if(pathname==='/login'){  /*顯示登陸頁面*/


        ejs.renderFile('views/form.ejs',{

        },function(err,data){
            res.end(data);
        })}else if(pathname==='/dologin' &&method==='get'){
        //get獲取數據
        console.log(url.parse(req.url,true).query);
        res.end('dologin');
    }else if(pathname==='/dologin' &&method==='post'){
        //post獲取數據
        var postStr ='';
        req.on('data',function (chunk) {
            postStr +=chunk;
        });

        req.on('end',function (err,chunk) {
            console.log(postStr);
            fs.appendFile('login.txt',postStr +'\n',function (err) {
                if (err){
                    console.log(err);
                }
                console.log('寫入文件成功');
            })

        })
    }else{
        res.end('other')
    }
}).listen(8001);
相關文章
相關標籤/搜索