express 와 koa 미들웨어 모델 비교
6417 단어 express
최근 에 koa 의 사용 을 배우 고 있 습 니 다.koa 는 상당히 기본 적 인 웹 프레임 워 크 이기 때문에 완전한 웹 응용 에 필요 한 것 은 대부분 미들웨어 형식 으로 도입 되 었 습 니 다.예 를 들 어 koa-router,koa-view 등 입 니 다.koa 의 문서 에서 언급 한 바 와 같이 koa 의 중간 부품 모델 은 express 와 다르다.koa 는 양파 형 이 고 express 는 직선 형 이다.왜 그런 지 에 대해 인터넷 의 많은 글 들 은 구체 적 으로 분석 하지 않 았 다.아니면 간단하게 async/await 의 특성 같은 거.이런 견해 의 옳 고 그 름 을 먼저 말 하지 않 고,나 에 게 있어 서 이런 견 해 는 여전히 너무 모호 하 다.그래서 나 는 소스 코드 를 통 해 양자 중간물 이 실현 하 는 원리 와 용법 의 공통점 과 차이 점 을 분석 하기 로 결정 했다.
간단하게 보기 위해 서 여기 express 는 connect 로 대체 합 니 다.
사용법
둘 다 홈 페이지(github)문 서 를 기준 으로
connect
다음은 홈 페이지 의 용법 입 니 다.
var connect = require('connect');
var http = require('http');
var app = connect();
// gzip/deflate outgoing responses
var compression = require('compression');
app.use(compression());
// store session state in browser cookie
var cookieSession = require('cookie-session');
app.use(cookieSession({
keys: ['secret1', 'secret2']
}));
// parse urlencoded request bodies into req.body
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: false}));
// respond to all requests
app.use(function(req, res){
res.end('Hello from Connect!
');
});
//create node.js http server and listen on port
http.createServer(app).listen(3000);
문서 에 따 르 면 connect 는 간단 한 경로 기능 을 제공 합 니 다.
app.use('/foo', function fooMiddleware(req, res, next) {
// req.url starts with "/foo"
next();
});
app.use('/bar', function barMiddleware(req, res, next) {
// req.url starts with "/bar"
next();
});
connect 의 미들웨어 는 선형 이 고 next 이후 에 다음 미들웨어 를 계속 찾 습 니 다.이런 모델 은 직관 적 으로 도 잘 이해 할 수 있 습 니 다.미들웨어 는 일련의 배열 입 니 다.경로 매 칭 을 통 해 해당 하 는 경로 의 처리 방법 을 찾 는 것 이 바로 미들웨어 입 니 다.사실 connect 도 이렇게 이 루어 졌 다.app.use 는 미들웨어 배열 에 새로운 미들웨어 를 넣 는 것 입 니 다.미들웨어 의 실행 은 개인 적 인 방법 app.handle 에 의 해 처리 되 고 express 도 마찬가지 입 니 다.
koa
connect 에 비해 koa 의 미들웨어 모델 은 직관 적 이지 않 고 인터넷 의 그림 을 빌려 표시 합 니 다.
즉,koa 가 중간 부품 을 처리 한 후에 다시 돌아 올 것 입 니 다.이것 은 우리 에 게 더욱 큰 조작 공간 을 주 었 습 니 다.koa 의 홈 페이지 인 스 턴 스 를 보 겠 습 니 다.
const Koa = require('koa');
const app = new Koa();
// x-response-time
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`);
});
// logger
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}`);
});
// response
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
분명 한 것 은 koa 처리 미들웨어 가 await next()를 만 났 을 때 현재 미들웨어 를 중단 하고 다음 미들웨어 를 처리 한 다음 에 고 개 를 돌려 남 은 임 무 를 계속 처리 하 는 것 이다.복잡 하지만 직관 적 으로 우 리 는 은은 하고 익숙 한 느낌 이 들 것 이다.바로 리 셋 함수 가 아 닐 까?여기 서 구체 적 인 실현 방법 은 말 하지 않 지만,확실히 반전 함수 이다.async/await 의 특성 과 는 아무런 관계 가 없습니다.소스 코드 분석
connect 와 koa 미들웨어 모델 차이 의 핵심 은 next 의 실현 에 있 습 니 다.양자 next 의 실현 을 간단하게 보 겠 습 니 다.
connect
connect 의 소스 코드 가 상당히 적 고 주석 도 200 줄 입 니 다.분명 해 보 입 니 다.connect 미들웨어 처 리 는 proto.handle 이라는 개인 적 인 방법 에 있 습 니 다.마찬가지 로 next 도 여기 서 이 루어 졌 습 니 다.
//
var index = 0
function next(err) {
//
var layer = stack[index++];
//
if (!layer) {
defer(done, err);
return;
}
// route data
var path = parseUrl(req).pathname || '/';
var route = layer.route;
//
// skip this layer if the route doesn't match
if (path.toLowerCase().substr(0, route.length) !== route.toLowerCase()) {
return next(err);
}
// call the layer handle
call(layer.handle, route, err, req, res, next);
}
혼 란 스 러 운 코드 를 삭제 한 후에 우 리 는 next 실현 도 매우 간결 하 다 는 것 을 볼 수 있다.재 귀적 호출 순서 로 미들웨어 를 찾 습 니 다.끊임없이 next 를 호출 합 니 다.코드 는 상당히 간단 하지만 생각 은 배 울 만하 다.그 중에서 done 은 제3자 처리 방법 이다.다른 sub app 및 경로 처리 부분 은 모두 삭제 되 었 습 니 다.중요 한 게 아니 라
koa
koa 는 next 의 실현 을 하나의 단독 가방 으로 분리 하여 코드 가 더욱 간단 하지만 더욱 복잡 해 보 이 는 기능 을 실현 했다.
function compose (middleware) {
return function (context, next) {
// last called middleware #
let index = -1
return dispatch(0)
function dispatch (i) {
index = i
try {
return Promise.resolve(fn(context, function next () {
return dispatch(i + 1)
}))
} catch (err) {
return Promise.reject(err)
}
}
}
}
위 에서 처리 한 코드 를 보면 서 어떤 학생 들 은 아직도 모 를 수도 있 습 니 다.그럼 계속 처리 하 겠 습 니 다.
function compose (middleware) {
return function (context, next) {
// last called middleware #
let index = -1
return dispatch(0)
function dispatch (i) {
index = i
let fn = middleware[i]
if (i === middleware.length) {
fn = next
}
if (!fn) return
return fn(context, function next () {
return dispatch(i + 1)
})
}
}
}
이렇게 되면 프로그램 이 더욱 간단 해 지고 async/await 와 아무런 관계 가 없 으 니 결 과 를 보 여 주세요.
var ms = [
function foo (ctx, next) {
console.log('foo1')
next()
console.log('foo2')
},
function bar (ctx, next) {
console.log('bar1')
next()
console.log('bar2')
},
function qux (ctx, next) {
console.log('qux1')
next()
console.log('qux2')
}
]
compose(ms)()
위의 프로그램 을 실행 하면 순서대로 출력 할 수 있 습 니 다.foo1
bar1
qux1
qux2
bar2
foo2
마찬가지 로 이른바 koa 의 양파 모델 이다.여기 서 우 리 는 이러한 결론 을 얻 을 수 있다.koa 의 중간 부품 모델 은 async 나 generator 와 실제 적 인 관 계 를 가지 지 않 고 koa 가 async 우선 을 강조 할 뿐이다.미들웨어 일시 정지 라 는 것 도 리 셋 함수 의 원인 일 뿐이다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
express를 사용하여 AWS S3 이미지에 액세스하기 위해 미리 서명된 URL을 생성하는 방법은 무엇입니까?이를 달성하는 방법 중 하나는 미리 서명된 URL을 사용하는 것입니다. However, the object owner can optionally share objects with others by creating a...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.