记阿里面试的一道nodejs中http同步处理请求问题

本文介绍了一种使用Node.js中的net模块实现HTTP同步请求的方法。通过建立TCP服务器并将请求排队处理,确保每次仅处理一个请求,直到完成后再处理队列中的下一个请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

刚刚面完阿里,问题中有一个问题是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");
        });
    });
}

测试结果如下:
这里写图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值