記阿里面試的一道nodejs中http同步處理請求問題


問題描述

剛剛面完阿里,問題中有一個問題是http模塊如何實現對請求的同步處理,也就是一個請求處理完后再去處理另一個請求。面試時腦子短路,不夠靈活沒有想到如何實現,只說了在request事件中只調用同步的方法,明顯不對嘛。哎,面完不一會,就想到了如何實現這個要求。

解決方案

開始只考慮到了http這個模塊,沒有考慮到net模塊,其實主要實現是通過net來實現的,先通過net建立服務器,然后將請求保存在一個隊列當中,然后從隊列中慢慢的處理請求,就能夠實現http的同步請求了。具體代碼如下:

const http = require("http");
const net  = require("net");

// 保存請求的隊列,每個元素都是一個socket
let watingQueue = [];

// 當前處理的請求
let curtSocket  = null;

let count = 0;

// 建立一個http服務器
let httpServer = http.createServer(function (req, res) {
    // 延遲一秒中回復
    setTimeout(function () {
        res.end(`request: ${++count}`, "utf8");
    }, 1000);

    res.on("finish", function () {
        curtSocket = null;
        // 一個請求結束了,處理下一個請求
        dealRequest();
    });
});

// 建立一個tcp的服務器(http協議是建立在tcp協議上的)
net.createServer(function (socket) {
    // 將請求壓入列隊
    enqueueSocket(socket);

    // 處理請求(如果現在真在處理的請求,不做任何處理)
    dealRequest();
}).listen(4000);

function enqueueSocket (socket) {
    watingQueue.push(socket);
}

function dealRequest () {
    if (curtSocket != null || watingQueue.length <= 0) {
        return;
    }

    curtSocket = watingQueue.shift();
    httpServer.emit("connection", curtSocket);  
}

測試

測試代碼如下:

let http = require("http");

let count = 10;
for (var i = 0; i < count; ++i) {
    request();
}

function request(i) {
    let startTime = Date.now();

    http.get("http://127.0.0.1:4000", function (res) {
        let str = "";

        res.setEncoding("utf8");

        res.on("data", function (data) {
            str += data;
        });

        res.on("end", function () {
            console.log("++++++++++++++++++++");
            console.log(str);
            console.log(`time ${Date.now() - startTime}`);
            console.log("--------------------\r\n");
        });
    });
}

測試結果如下:
這里寫圖片描述


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com