跳到主要内容

application.js

实现


const http = require("http");
const context = require("./context");
const request = require("./request");
const response = require("./response");
const EventEmitter = require("events");
const Stream = require("stream");

class Application extends EventEmitter {
constructor(props) {
super(props);
this.context = Object.create(context);
this.request = Object.create(request);
this.response = Object.create(response);
this.middlewares = [];
}
use(middleware) {
this.middlewares.push(middleware);
}
createContext(req, res) {
let ctx = Object.create(this.context);
let request = Object.create(this.request);
let response = Object.create(this.response);

ctx.request = request;
ctx.response = response;
ctx.request.req = ctx.req = req;
ctx.response.res = ctx.res = res;

return ctx;
}
compose(ctx) {
const dispatch = (i) => {
if (i === this.middlewares.length) {
return Promise.resolve();
}
let middleware = this.middlewares[i];
try {
return Promise.resolve(middleware(ctx, () => dispatch(i + 1)));
} catch (error) {
return Promise.reject(error);
}
};
return dispatch(0);
}
handleRequest = (req, res) => {
let ctx = this.createContext(req, res);
this.compose(ctx)
.then(() => {
if (ctx.body instanceof Stream) {
ctx.res.setHeader("Content-Type", "application/octet-stream");
ctx.body.pipe(res);
} else {
res.end(ctx.body);
}
})
.catch((error) => {
this.emit("error", error);
});
};
listen() {
const server = http.createServer(this.handleRequest);
server.listen(...arguments);
}
}

module.exports = Application;