资讯专栏INFORMATION COLUMN

在?用Node.js实现一个http服务器框架?

Vicky / 2369人阅读

摘要:功能演进基础服务器支持中间件支持异步中间件切换为装饰增强细化统一异常处理细化流程控制自定义注解拦截管理注入组件标记自动处理返回值事务缓存框架权限认证策略模式装饰模式

功能演进: V1:

基础http服务器

支持中间件

支持异步中间件

V1.x:

JS切换为TS

request/response装饰增强

细化统一异常处理

细化流程控制

V2:

AOP自定义注解拦截

IOC管理注入@Controller/@Service组件

@Request标记handler

@ResponseBody自动处理返回值

事务

V2.x:

缓存框架

权限认证(AOP,策略模式,装饰模式)

V1: SOS.js
const http = require("http");
const url = require("url");
const EventEmitter = require("events");

const compose = (ctx) => (...funcs) => {
    if (funcs.length === 0) {
        return arg => arg
    }
    let lastIndex = funcs.length - 1;
    return funcs.reduceRight((a, b, index) => b(() => {
        if (index === funcs.length - 1) {
            return Promise.resolve();
        }
        if (lastIndex !== index) {
            return Promise.reject(new Error("can not call next() over once!"))
        }
        lastIndex--;
        try {
            return Promise.resolve(a(ctx));
        } catch (e) {
            return Promise.reject(e);
        }
    }), 1);
};


const applyMiddleware = (middles, ctx) => compose(ctx)(...middles);

class SOS extends EventEmitter {
    constructor() {
        this.middleWares = [];
        this.serve = http.createServer(async (req, res) => {
            const ctx = { req, res };
            const handler = applyMiddleware(this.middleWares, ctx);
            await handler(ctx);
            res.finisn || res.end();
        });
    }

    use(mid) {
        this.middleWares.push(mid);
    }

    listen(...agr) {
        this.serve.listen(...agr);
        console.log("starting");
    }

    onerror(err, ctx) {
        if (err.code === "ENOENT") {
            ctx.status = 404;
        }
        else {
            ctx.status = 500;
        }
        let msg = err.message || "000 error";
        ctx.res.end(msg);

        this.emit("error", err);
    }
}
test.js
const sos = new SOS();
sos.listen(9009);

sos.use((next) =>async (ctx) => {
    console.log("
pathname::",url.parse(ctx.req.url).pathname);
    ctx.res.write(new Date()+"");
    console.log("before 111");
    ctx.res.write("before 111
");
    await next();
    console.log("after 111");
    ctx.res.write("after 111
");
});
sos.use((next) =>async (ctx) => {
    console.log("before 222");
    ctx.res.write("before 222
");
    await next();
    console.log("after 222");
    ctx.res.write("end test222
");
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log("timeout 222 ");
        ctx.res.write("timeout 222 
");
        return resolve();
      }, 3000);
    });
});
sos.use((next) =>async (ctx) => {
    console.log("before 333");
    ctx.res.write("before 333
");
    await next();
    console.log("after 333");
    ctx.res.write("end test333
");
});


文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/110006.html

相关文章

  • Express 实战(一):概览

    摘要:一个标准性的事件就是年的横空出世。引擎快速处理能力和异步编程风格,让开发者从多线程中解脱了出来。其次,通过异步编程范式将其高并发的能力发挥的淋漓尽致。它也仅仅是一个处理请求并作出响应的函数,并无任何特殊之处。 showImg(https://segmentfault.com/img/remote/1460000010819116); 在正式学习 Express 内容之前,我们有必要从大...

    zhaochunqi 评论0 收藏0
  • Node Hero】4. 第一个 Node.js HTTP 务器

    摘要:本文转载自众成翻译译者网络埋伏纪事链接原文本章我会指导你启动一个简单的服务器,并开始为请求服务。现在,我们开始创建第一个服务器我们将模块,并将服务器绑定到端口来监听。必须用如下方式启动服务器总结本章学习了如何从头开始创建第一个服务器。 本文转载自:众成翻译译者:网络埋伏纪事链接:http://www.zcfy.cc/article/1750原文:https://blog.risings...

    Coly 评论0 收藏0
  • 【全文】狼叔:如何正确的学习Node.js

    摘要:感谢大神的免费的计算机编程类中文书籍收录并推荐地址,以后在仓库里更新地址,声音版全文狼叔如何正确的学习简介现在,越来越多的科技公司和开发者开始使用开发各种应用。 说明 2017-12-14 我发了一篇文章《没用过Node.js,就别瞎逼逼》是因为有人在知乎上黑Node.js。那篇文章的反响还是相当不错的,甚至连著名的hax贺老都很认同,下班时读那篇文章,竟然坐车的还坐过站了。大家可以很...

    Edison 评论0 收藏0
  • 【全文】狼叔:如何正确的学习Node.js

    摘要:感谢大神的免费的计算机编程类中文书籍收录并推荐地址,以后在仓库里更新地址,声音版全文狼叔如何正确的学习简介现在,越来越多的科技公司和开发者开始使用开发各种应用。 说明 2017-12-14 我发了一篇文章《没用过Node.js,就别瞎逼逼》是因为有人在知乎上黑Node.js。那篇文章的反响还是相当不错的,甚至连著名的hax贺老都很认同,下班时读那篇文章,竟然坐车的还坐过站了。大家可以很...

    fengxiuping 评论0 收藏0

发表评论

0条评论

Vicky

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<