Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
Koa2¿ò¼ÜÔ­Àí½âÎöºÍʵÏÖ
 
  10392  次浏览      27
  2019-1-15
 
±à¼­ÍƼö:
±¾ÎÄÀ´×Ôcsdn£¬ÎÄÕ½éÉÜÁËkoa2Ô´ÂëµÄ´óÌå¿ò¼Ü½á¹¹¡¢ÊµÏÖkoa¿ò¼ÜÐèÒªµÄËĸö´óÄ£¿éµÈÏà¹ØÄÚÈÝ¡£

koaÊÇÒ»¸ö»ùÓÚnodeʵÏÖµÄÒ»¸öеÄweb¿ò¼Ü£¬ËüÊÇÓÉexpress¿ò¼ÜµÄÔ­°àÈËÂí´òÔìµÄ¡£ËüµÄÌØµãÊÇÓÅÑÅ¡¢¼ò½à¡¢±í´ïÁ¦Ç¿¡¢×ÔÓɶȸߡ£Ëü¸üexpressÏà±È£¬ËüÊÇÒ»¸ö¸üÇáÁ¿µÄnode¿ò¼Ü£¬ÒòΪËüËùÓй¦Äܶ¼Í¨¹ý²å¼þʵÏÖ£¬ÕâÖÖ²å°ÎʽµÄ¼Ü¹¹Éè¼ÆÄ£Ê½£¬ºÜ·ûºÏunixÕÜѧ¡£

koa¿ò¼ÜÏÖÔÚ¸üе½ÁË2.x°æ±¾£¬±¾ÎÄ´ÓÁ㿪ʼ£¬Ñ­Ðò½¥½ø£¬½²½âkoa2µÄ¿ò¼ÜÔ´Âë½á¹¹ºÍʵÏÖÔ­Àí£¬Õ¹Ê¾ºÍÏê½âkoa2¿ò¼ÜÔ´ÂëÖеö×îÖØÒªµÄ¸ÅÄȻºóÊÖ°ÑÊ̴ֽó¼ÒÇ××ÔʵÏÖÒ»¸ö¼òÒ×µÄkoa2¿ò¼Ü£¬°ïÖú´ó¼ÒѧϰºÍ¸üÉî²ã´ÎµÄÀí½âkoa2£¬¿´Íê±¾ÎÄÒÔºó£¬ÔÙÈ¥¶ÔÕÕkoa2µÄÔ´Âë½øÐв鿴£¬ÏàÐÅÄãµÄ˼·½«»á·Ç³£µÄ˳³©¡£

±¾ÎÄËùÓõĿò¼ÜÊÇkoa2£¬Ëü¸úkoa1²»Í¬£¬koa1ʹÓõÄÊÇgenerator+co.jsµÄÖ´Ðз½Ê½£¬¶økoa2ÖÐʹÓÃÁËasync/await£¬Òò´Ë±¾ÎĵĴúÂëºÍdemoÐèÒªÔËÐÐÔÚnode 8°æ±¾¼°ÆäÒÔÉÏ£¬Èç¹û¶ÁÕßµÄnode°æ±¾½ÏµÍ£¬½¨ÒéÉý¼¶»òÕß°²×°babel-cli£¬ÓÃÆäÖеÄbabel-nodeÀ´ÔËÐб¾ÎÄÉæ¼°µ½µÄ´úÂë¡£

koaÔ´Âë½á¹¹

ÉÏͼÊÇkoa2µÄÔ´ÂëĿ¼½á¹¹µÄlibÎļþ¼Ð£¬libÎļþ¼ÐÏ·Å×ÅËĸökoa2µÄºËÐÄÎļþ£ºapplication.js¡¢context.js¡¢request.js¡¢response.js¡£

application.js

application.jsÊÇkoaµÄÈë¿ÚÎļþ£¬ËüÏòÍâµ¼³öÁË´´½¨classʵÀýµÄ¹¹Ô캯Êý£¬Ëü¼Ì³ÐÁËevents£¬ÕâÑù¾Í»á¸³Óè¿ò¼Üʼþ¼àÌýºÍʼþ´¥·¢µÄÄÜÁ¦¡£application»¹±©Â¶ÁËһЩ³£ÓõÄapi£¬±ÈÈçtoJSON¡¢listen¡¢useµÈµÈ¡£

listenµÄʵÏÖÔ­ÀíÆäʵ¾ÍÊǶÔhttp.createServer½øÐÐÁËÒ»¸ö·â×°£¬ÖصãÊÇÕâ¸öº¯ÊýÖд«ÈëµÄcallback£¬ËüÀïÃæ°üº¬ÁËÖмä¼þµÄºÏ²¢£¬ÉÏÏÂÎĵĴ¦Àí£¬¶ÔresµÄÌØÊâ´¦Àí¡£

useÊÇÊÕ¼¯Öмä¼þ£¬½«¶à¸öÖмä¼þ·ÅÈëÒ»¸ö»º´æ¶ÓÁÐÖУ¬È»ºóͨ¹ýkoa-composeÕâ¸ö²å¼þ½øÐеݹé×éºÏµ÷ÓÃÕâһЩÁеÄÖмä¼þ¡£

context.js

Õⲿ·Ö¾ÍÊÇkoaµÄÓ¦ÓÃÉÏÏÂÎÄctx,Æäʵ¾ÍÒ»¸ö¼òµ¥µÄ¶ÔÏó±©Â¶£¬ÀïÃæµÄÖØµãÔÚdelegate£¬Õâ¸ö¾ÍÊÇ´úÀí£¬Õâ¸ö¾ÍÊÇΪÁË¿ª·¢Õß·½±ã¶øÉè¼ÆµÄ£¬±ÈÈçÎÒÃÇÒª·ÃÎÊctx.repsponse.statusµ«ÊÇÎÒÃÇͨ¹ýdelegate£¬¿ÉÒÔÖ±½Ó·ÃÎÊctx.status·ÃÎʵ½Ëü¡£

request.js¡¢response.js

ÕâÁ½²¿·Ö¾ÍÊǶÔÔ­ÉúµÄres¡¢reqµÄһЩ²Ù×÷ÁË£¬´óÁ¿Ê¹ÓÃes6µÄgetºÍsetµÄһЩÓï·¨£¬È¥È¡headers»òÕßÉèÖÃheaders¡¢»¹ÓÐÉèÖÃbodyµÈµÈ£¬ÕâЩ¾Í²»Ïêϸ½éÉÜÁË£¬ÓÐÐËȤµÄ¶ÁÕß¿ÉÒÔ×ÔÐп´Ô´Âë¡£

ʵÏÖkoa2µÄËÄ´óÄ£¿é

ÉÏÎļòÊöÁËkoa2Ô´ÂëµÄ´óÌå¿ò¼Ü½á¹¹£¬½ÓÏÂÀ´ÎÒÃÇÀ´ÊµÏÖÒ»¸ökoa2µÄ¿ò¼Ü£¬±ÊÕßÈÏΪÀí½âºÍʵÏÖÒ»¸ökoa¿ò¼ÜÐèҪʵÏÖËĸö´óÄ£¿é£¬·Ö±ðÊÇ£º

·â×°node http server¡¢´´½¨KoaÀ๹Ô캯Êý

¹¹Ôìrequest¡¢response¡¢context¶ÔÏó

Öмä¼þ»úÖÆºÍ°þÑó´ÐÄ£Ð͵ÄʵÏÖ

´íÎó²¶»ñºÍ´íÎó´¦Àí

ÏÂÃæÎÒÃǾÍÖðÒ»·ÖÎöºÍʵÏÖ¡£

Ä£¿éÒ»£º·â×°node http serverºÍ´´½¨KoaÀ๹Ô캯Êý

ÔĶÁkoa2µÄÔ´ÂëµÃÖª£¬ÊµÏÖkoaµÄ·þÎñÆ÷Ó¦ÓúͶ˿ڼàÌý£¬Æäʵ¾ÍÊÇ»ùÓÚnodeµÄÔ­Éú´úÂë½øÐÐÁË·â×°£¬ÈçÏÂͼµÄ´úÂë¾ÍÊÇͨ¹ýnodeÔ­Éú´úÂëʵÏֵķþÎñÆ÷¼àÌý¡£

let http = require('http');
let server = http.createServer((req, res) => {
res.writeHead(200);
res.end('hello world');
});
server.listen(3000, () => {
console.log('listenning on 3000');
});

ÎÒÃÇÐèÒª½«ÉÏÃæµÄnodeÔ­Éú´úÂë·âװʵÏÖ³ÉkoaµÄģʽ£º

const http = require('http');
const Koa = require('koa');
const app = new Koa();
app.listen(3000);

ʵÏÖkoaµÄµÚÒ»²½¾ÍÊǶÔÒÔÉϵÄÕâ¸ö¹ý³Ì½øÐзâ×°£¬Îª´ËÎÒÃÇÐèÒª´´½¨application.jsʵÏÖÒ»¸öApplicationÀàµÄ¹¹Ô캯Êý£º

let http = require('http');
class Application {
constructor() {
this.callbackFunc;
}
listen(port) {
let server = http.createServer(this.callback());
server.listen(port);
}
use(fn) {
this.callbackFunc = fn;
}
callback() {
return (req, res) => {
this.callbackFunc(req, res);
};
}
}
module.exports = Application;

È»ºó´´½¨example.js£¬ÒýÈëapplication.js£¬ÔËÐзþÎñÆ÷ʵÀýÆô¶¯¼àÌý´úÂ룺

let Koa = require('./application');
let app = new Koa();
app.use((req, res) => {
res.writeHead(200);
res.end('hello world');
});
app.listen(3000, () => {
console.log('listening on 3000');
});

ÏÖÔÚÔÚä¯ÀÀÆ÷ÊäÈëlocalhost:3000¼´¿É¿´µ½ä¯ÀÀÆ÷ÀïÏÔʾ¡°hello world¡±¡£ÏÖÔÚµÚÒ»²½ÎÒÃÇÒѾ­Íê³ÉÁË£¬¶Ôhttp server½øÐÐÁ˼òµ¥µÄ·â×°ºÍ´´½¨ÁËÒ»¸ö¿ÉÒÔÉú³ÉkoaʵÀýµÄÀàclass£¬Õâ¸öÀàÀﻹʵÏÖÁËapp.useÓÃÀ´×¢²áÖмä¼þºÍ×¢²á»Øµ÷º¯Êý£¬app.listenÓÃÀ´¿ªÆô·þÎñÆ÷ʵÀý²¢´«Èëcallback»Øµ÷º¯Êý£¬µÚһģ¿éÖ÷ÒªÊÇʵÏÖµäÐ͵Äkoa·ç¸ñºÍ´îºÃÁËÒ»¸ökoaµÄ¼òµ¥µÄ¼Ü×Ó¡£½ÓÏÂÀ´ÎÒÃÇ¿ªÊ¼±àдºÍ½²½âµÚ¶þÄ£¿é¡£

Ä£¿é¶þ£º¹¹Ôìrequest¡¢response¡¢context¶ÔÏó

ÔĶÁkoa2µÄÔ´ÂëµÃÖª£¬ÆäÖÐcontext.js¡¢request.js¡¢response.jsÈý¸öÎļþ·Ö±ðÊÇrequest¡¢response¡¢contextÈý¸öÄ£¿éµÄ´úÂëÎļþ¡£context¾ÍÊÇÎÒÃÇÆ½Ê±Ð´koa´úÂëʱµÄctx£¬ËüÏ൱ÓÚÒ»¸öÈ«¾ÖµÄkoaʵÀýÉÏÏÂÎÄthis£¬ËüÁ¬½ÓÁËrequest¡¢responseÁ½¸ö¹¦ÄÜÄ£¿é£¬²¢ÇÒ±©Â¶¸økoaµÄʵÀýºÍÖмä¼þµÈ»Øµ÷º¯ÊýµÄ²ÎÊýÖУ¬Æðµ½³ÐÉÏÆôϵÄ×÷Óá£

request¡¢responseÁ½¸ö¹¦ÄÜÄ£¿é·Ö±ð¶ÔnodeµÄÔ­Éúrequest¡¢response½øÐÐÁËÒ»¸ö¹¦Äܵķâ×°£¬Ê¹ÓÃÁËgetterºÍsetterÊôÐÔ£¬»ùÓÚnodeµÄ¶ÔÏóreq/res¶ÔÏó·â×°koaµÄrequest/response¶ÔÏó¡£ÎÒÃÇ»ùÓÚÕâ¸öÔ­Àí¼òµ¥ÊµÏÖÒ»ÏÂrequest.js¡¢response.js£¬Ê×ÏÈ´´½¨request.jsÎļþ£¬È»ºóдÈëÒÔÏ´úÂ룺

let url = require('url');
module.exports = {
get query() {
return url.parse(this.req.url, true).query;
}
};

ÕâÑùµ±ÄãÔÚkoaʵÀýÀïʹÓÃctx.queryµÄʱºò£¬¾Í»á·µ»Øurl.parse(this.req.url, true).queryµÄÖµ¡£¿´Ô´Âë¿ÉÖª£¬»ùÓÚgetterºÍsetter£¬ÔÚrequest.jsÀﻹ·â×°ÁËheader¡¢url¡¢origin¡¢pathµÈ·½·¨£¬¶¼ÊǶÔÔ­ÉúµÄrequestÉÏÓÃgetterºÍsetter½øÐÐÁË·â×°£¬±ÊÕß²»ÔÙÕâÀïһһʵÏÖ¡£

½ÓÏÂÀ´ÎÒÃÇʵÏÖresponse.jsÎļþ´úÂëÄ£¿é£¬ËüºÍrequestÔ­ÀíÒ»Ñù£¬Ò²ÊÇ»ùÓÚgetterºÍsetter¶ÔÔ­Éúresponse½øÐÐÁË·â×°£¬ÄÇÎÒÃǽÓÏÂÀ´Í¨¹ý¶Ô³£ÓõÄctx.bodyºÍctx.statusÕâ¸öÁ½¸öÓï¾äµ±×öÀý×Ó¼òÊöÒ»ÏÂÈç¹ûʵÏÖkoaµÄresponseµÄÄ£¿é£¬ÎÒÃÇÊ×ÏÈ´´½¨ºÃresponse.jsÎļþ£¬È»ºóÊäÈëÏÂÃæµÄ´úÂ룺

module.exports = {
get body() {
return this._body;
},
set body(data) {
this._body = data;
},
get status() {
return this.res.statusCode;
},
set status(statusCode) {
if (typeof statusCode !== 'number') {
throw new Error('something wrong!');
}
this.res.statusCode = statusCode;
}
};

ÒÔÉÏ´úÂëʵÏÖÁ˶ÔkoaµÄstatusµÄ¶ÁÈ¡ºÍÉèÖ㬶ÁÈ¡µÄʱºò·µ»ØµÄÊÇ»ùÓÚÔ­ÉúµÄresponse¶ÔÏóµÄstatusCodeÊôÐÔ£¬¶øbodyµÄ¶ÁÈ¡ÔòÊǶÔthis._body½øÐжÁдºÍ²Ù×÷¡£ÕâÀï¶Ôbody½øÐвÙ×÷²¢Ã»ÓÐʹÓÃÔ­ÉúµÄthis.res.end£¬ÒòΪÔÚÎÒÃDZàдkoa´úÂëµÄʱºò£¬»á¶Ôbody½øÐжà´ÎµÄ¶ÁÈ¡ºÍÐ޸ģ¬ËùÒÔÕæÕý·µ»Øä¯ÀÀÆ÷ÐÅÏ¢µÄ²Ù×÷ÊÇÔÚapplication.jsÀï½øÐзâ×°ºÍ²Ù×÷¡£

ÏÖÔÚÎÒÃÇÒѾ­ÊµÏÖÁËrequest.js¡¢response.js£¬»ñÈ¡µ½ÁËrequest¡¢response¶ÔÏóºÍËûÃǵķâ×°µÄ·½·¨£¬È»ºóÎÒÃÇ¿ªÊ¼ÊµÏÖcontext.js£¬contextµÄ×÷ÓþÍÊǽ«request¡¢response¶ÔÏó¹ÒÔØµ½ctxµÄÉÏÃæ£¬ÈÃkoaʵÀýºÍ´úÂëÄÜ·½±ãµÄʹÓõ½request¡¢response¶ÔÏóÖеķ½·¨¡£ÏÖÔÚÎÒÃÇ´´½¨context.jsÎļþ£¬ÊäÈëÈçÏ´úÂ룺

let proto = {};

function delegateSet(property, name) {
proto.__defineSetter__(name, function (val) {
this[property][name] = val;
});
}

function delegateGet(property, name) {
proto.__defineGetter__(name, function () {
return this[property][name];
});
}

let requestSet = [];
let requestGet = ['query'];

let responseSet = ['body', 'status'];
let responseGet = responseSet;

requestSet.forEach(ele => {
delegateSet('request', ele);
});

requestGet.forEach(ele => {
delegateGet('request', ele);
});

responseSet.forEach(ele => {
delegateSet('response', ele);
});

responseGet.forEach(ele => {
delegateGet('response', ele);
});

module.exports = proto;

context.jsÎļþÖ÷ÒªÊǶԳ£ÓõÄrequestºÍresponse·½·¨½øÐйÒÔØºÍ´úÀí£¬Í¨¹ýcontext.queryÖ±½Ó´úÀíÁËcontext.request.query£¬context.bodyºÍcontext.status´úÀíÁËcontext.response.bodyÓëcontext.response.status¡£¶øcontext.request£¬context.responseÔò»áÔÚapplication.jsÖйÒÔØ

±¾À´¿ÉÒÔÓüòµ¥µÄsetterºÍgetterÈ¥ÉèÖÃÿһ¸ö·½·¨£¬µ«ÊÇÓÉÓÚcontext¶ÔÏó¶¨Òå·½·¨±È½Ï¼òµ¥ºÍ¹æ·¶£¬ÔÚkoaÔ´ÂëÀï¿ÉÒÔ¿´µ½£¬koaÔ´ÂëÓõÄÊÇdefineSetterºÍdefineSetterÀ´´úÌæsetter/getterÿһ¸öÊôÐԵĶÁÈ¡ÉèÖã¬ÕâÑù×öÖ÷ÒªÊÇ·½±ãÍØÕ¹ºÍ¾«¼òÁËд·¨£¬µ±ÎÒÃÇÐèÒª´úÀí¸ü¶àµÄresºÍreqµÄ·½·¨µÄʱºò£¬¿ÉÒÔÏòcontext.jsÎļþÀïÃæµÄÊý×é¶ÔÏóÀïÃæÌí¼Ó¶ÔÓ¦µÄ·½·¨ÃûºÍÊôÐÔÃû¼´¿É¡£

ĿǰΪֹ£¬ÎÒÃÇÒѾ­µÃµ½ÁËrequest¡¢response¡¢contextÈý¸öÄ£¿é¶ÔÏóÁË£¬½ÓÏÂÀ´¾ÍÊǽ«request¡¢responseËùÓз½·¨¹ÒÔØµ½contextÏ£¬ÈÃcontextʵÏÖËüµÄ³ÐÉÏÆôϵÄ×÷Óã¬ÐÞ¸Äapplication.jsÎļþ£¬Ìí¼ÓÈçÏ´úÂ룺

let http = require('http');
let context = require('./context');
let request = require('./request');
let response = require('./response');

createContext(req, res) {
let ctx = Object.create(this.context);
ctx.request = Object.create(this.request);
ctx.response = Object.create(this.response);
ctx.req = ctx.request.req = req;
ctx.res = ctx.response.res = res;
return ctx;
}

¿ÉÒÔ¿´µ½£¬ÎÒÃÇÌí¼ÓÁËcreateContextÕâ¸ö·½·¨£¬Õâ¸ö·½·¨Êǹؼü£¬Ëüͨ¹ýObject.create´´½¨ÁËctx£¬²¢½«requestºÍresponse¹ÒÔØµ½ÁËctxÉÏÃæ£¬½«Ô­ÉúµÄreqºÍres¹ÒÔØµ½ÁËctxµÄ×ÓÊôÐÔÉÏ£¬Íù»Ø¿´Ò»ÏÂcontext/request/response.jsÎļþ£¬¾ÍÄÜÖªµÀµ±Ê±Ê¹ÓõÄthis.res»òÕßthis.responseÖ®ÀàµÄÊÇ´ÓÄÄÀïÀ´µÄÁË£¬Ô­À´ÊÇÔÚÕâ¸öcreateContext·½·¨ÖйÒÔØµ½Á˶ÔÓ¦µÄʵÀýÉÏ£¬¹¹½¨ÁËÔËÐÐʱÉÏÏÂÎÄctxÖ®ºó£¬ÎÒÃǵÄapp.use»Øµ÷º¯Êý²ÎÊý¾Í¶¼»ùÓÚctxÁË¡£

Ä£¿éÈý£ºÖмä¼þ»úÖÆºÍ°þÑó´ÐÄ£Ð͵ÄʵÏÖ

ĿǰΪֹÎÒÃÇÒѾ­³É¹¦ÊµÏÖÁËÉÏÏÂÎÄcontext¶ÔÏó¡¢ ÇëÇórequest¶ÔÏóºÍÏìÓ¦response¶ÔÏóÄ£¿é£¬»¹²îÒ»¸ö×îÖØÒªµÄÄ£¿é£¬¾ÍÊÇkoaµÄÖмä¼þÄ£¿é£¬koaµÄÖмä¼þ»úÖÆÊÇÒ»¸ö°þÑó´ÐʽµÄÄ£ÐÍ£¬¶à¸öÖмä¼þͨ¹ýuse·Å½øÒ»¸öÊý×é¶ÓÁÐÈ»ºó´ÓÍâ²ã¿ªÊ¼Ö´ÐУ¬Óöµ½nextºó½øÈë¶ÓÁÐÖеÄÏÂÒ»¸öÖмä¼þ£¬ËùÓÐÖмä¼þÖ´ÐÐÍêºó¿ªÊ¼»ØÖ¡£¬Ö´ÐжÓÁÐÖÐ֮ǰÖмä¼þÖÐδִÐеĴúÂ벿·Ö£¬Õâ¾ÍÊǰþÑó´ÐÄ£ÐÍ£¬koaµÄÖмä¼þ»úÖÆ¡£

koaµÄ°þÑó´ÐÄ£ÐÍÔÚkoa1ÖÐʹÓõÄÊÇgenerator + co.jsȥʵÏֵģ¬koa2ÔòʹÓÃÁËasync/await + PromiseȥʵÏֵ쬽ÓÏÂÀ´ÎÒÃÇ»ùÓÚasync/await + PromiseȥʵÏÖkoa2ÖеÄÖмä¼þ»úÖÆ¡£Ê×ÏÈ£¬¼ÙÉèµ±koaµÄÖмä¼þ»úÖÆÒѾ­×öºÃÁË£¬ÄÇôËüÊÇÄܳɹ¦ÔËÐÐÏÂÃæ´úÂëµÄ£º

let Koa = require('../src/application');

let app = new Koa();

app.use(async (ctx, next) => {
console.log(1);
await next();
console.log(6);
});

app.use(async (ctx, next) => {
console.log(2);
await next();
console.log(5);
});

app.use(async (ctx, next) => {
console.log(3);
ctx.body = "hello world";
console.log(4);
});

app.listen(3000, () => {
console.log('listenning on 3000');
});

ÔËÐгɹ¦ºó»áÔÚÖÕ¶ËÊä³ö123456£¬ÄǾÍÄÜÑéÖ¤ÎÒÃǵÄkoaµÄ°þÑó´ÐÄ£ÐÍÊÇÕýÈ·µÄ¡£½ÓÏÂÀ´ÎÒÃÇ¿ªÊ¼ÊµÏÖ£¬ÐÞ¸Äapplication.jsÎļþ£¬Ìí¼ÓÈçÏ´úÂ룺

compose() {
return async ctx => {
function createNext(middleware, oldNext) {
return async () => {
await middleware(ctx, oldNext);
}
}
let len = this.middlewares.length;
let next = async () => {
return Promise.resolve();
};
for (let i = len - 1; i >= 0; i--) {
let currentMiddleware = this.middlewares[i];
next = createNext(currentMiddleware, next);
}
await next();
};
}

callback() {
return (req, res) => {
let ctx = this.createContext(req, res);
let respond = () => this.responseBody(ctx);
let onerror = (err) => this.onerror(err, ctx);
let fn = this.compose();
return fn(ctx);
};
}

koaͨ¹ýuseº¯Êý£¬°ÑËùÓеÄÖмä¼þpushµ½Ò»¸öÄÚ²¿Êý×é¶ÓÁÐthis.middlewaresÖУ¬°þÑó´ÐÄ£ÐÍÄÜÈÃËùÓеÄÖмä¼þÒÀ´ÎÖ´ÐУ¬Ã¿´ÎÖ´ÐÐÍêÒ»¸öÖмä¼þ£¬Óöµ½next()¾Í»á½«¿ØÖÆÈ¨´«µÝµ½ÏÂÒ»¸öÖмä¼þ£¬ÏÂÒ»¸öÖмä¼þµÄnext²ÎÊý£¬°þÑó´ÐÄ£Ð͵Ä×î¹Ø¼ü´úÂëÊÇcomposeÕâ¸öº¯Êý£º

compose() {
return async ctx => {
function createNext(middleware, oldNext) {
return async () => {
await middleware(ctx, oldNext);
}
}
let len = this.middlewares.length;
let next = async () => {
return Promise.resolve();
};
for (let i = len - 1; i >= 0; i--) {
let currentMiddleware = this.middlewares[i];
next = createNext(currentMiddleware, next);
}
await next();
};
}

createNextº¯ÊýµÄ×÷ÓþÍÊǽ«ÉÏÒ»¸öÖмä¼þµÄnextµ±×ö²ÎÊý´«¸øÏÂÒ»¸öÖмä¼þ£¬²¢ÇÒ½«ÉÏÏÂÎÄctx°ó¶¨µ±Ç°Öмä¼þ£¬µ±Öмä¼þÖ´ÐÐÍ꣬µ÷ÓÃnext()µÄʱºò£¬Æäʵ¾ÍÊÇÈ¥Ö´ÐÐÏÂÒ»¸öÖмä¼þ¡£

for (let i = len - 1; i >= 0; i--) {
let currentMiddleware = this.middlewares[i];
next = createNext(currentMiddleware, next);
}

ÉÏÃæÕâ¶Î´úÂëÆäʵ¾ÍÊÇÒ»¸öÁ´Ê½·´ÏòµÝ¹éÄ£Ð͵ÄʵÏÖ£¬iÊÇ´Ó×î´óÊý¿ªÊ¼Ñ­»·µÄ£¬½«Öмä¼þ´Ó×îºóÒ»¸ö¿ªÊ¼·â×°£¬Ã¿Ò»´Î¶¼Êǽ«×Ô¼ºµÄÖ´Ðк¯Êý·â×°³Énextµ±×öÉÏÒ»¸öÖмä¼þµÄnext²ÎÊý£¬ÕâÑùµ±Ñ­»·µ½µÚÒ»¸öÖмä¼þµÄʱºò£¬Ö»ÐèÒªÖ´ÐÐÒ»´Înext()£¬¾ÍÄÜÁ´Ê½µÄµÝ¹éµ÷ÓÃËùÓÐÖмä¼þ£¬Õâ¸ö¾ÍÊÇkoa°þÑó´ÐµÄºËÐÄ´úÂë»úÖÆ¡£

µ½ÕâÀïÎÒÃÇ×ܽáÒ»ÏÂÉÏÃæËùÓаþÑó´ÐÄ£ÐÍ´úÂëµÄÁ÷³Ì£¬Í¨¹ýuse´«½øÀ´µÄÖмä¼þÊÇÒ»¸ö»Øµ÷º¯Êý£¬»Øµ÷º¯ÊýµÄ²ÎÊýÊÇctxÉÏÏÂÎĺÍnext£¬nextÆäʵ¾ÍÊÇ¿ØÖÆÈ¨µÄ½»½Ó°ô£¬nextµÄ×÷ÓÃÊÇÍ£Ö¹ÔËÐе±Ç°Öмä¼þ£¬½«¿ØÖÆÈ¨½»¸øÏÂÒ»¸öÖмä¼þ£¬Ö´ÐÐÏÂÒ»¸öÖмä¼þµÄnext()֮ǰµÄ´úÂ룬µ±ÏÂÒ»¸öÖмä¼þÔËÐеĴúÂëÓöµ½ÁËnext()£¬ÓֻὫ´úÂëÖ´ÐÐȨ½»¸øÏÂϸöÖмä¼þ£¬µ±Ö´Ðе½×îºóÒ»¸öÖмä¼þµÄʱºò£¬¿ØÖÆÈ¨·¢Éú·´×ª£¬¿ªÊ¼»ØÍ·È¥Ö´ÐÐ֮ǰËùÓÐÖмä¼þÖÐÊ£ÏÂδִÐеĴúÂ룬ÕâÕû¸öÁ÷³ÌÓеãÏñÒ»¸öαµÝ¹é£¬µ±×îÖÕËùÓÐÖмä¼þÈ«²¿Ö´ÐÐÍêºó£¬»á·µ»ØÒ»¸öPromise¶ÔÏó£¬ÒòΪÎÒÃǵÄcomposeº¯Êý·µ»ØµÄÊÇÒ»¸öasyncµÄº¯Êý£¬asyncº¯ÊýÖ´ÐÐÍêºó»á·µ»ØÒ»¸öPromise£¬ÕâÑùÎÒÃǾÍÄܽ«ËùÓеÄÖмä¼þÒì²½Ö´ÐÐͬ²½»¯£¬Í¨¹ýthen¾Í¿ÉÒÔÖ´ÐÐÏìÓ¦º¯ÊýºÍ´íÎó´¦Àíº¯Êý¡£

µ±Öмä¼þ»úÖÆ´úÂëдºÃÁËÒÔºó£¬ÔËÐÐÎÒÃǵÄÉÏÃæµÄÀý×Ó£¬ÒѾ­ÄÜÊä³ö123456ÁË£¬ÖÁ´Ë£¬ÎÒÃǵÄkoaµÄ»ù±¾¿ò¼ÜÒѾ­»ù±¾×öºÃÁË£¬²»¹ýÒ»¸ö¿ò¼Ü²»ÄÜֻʵÏÖ¹¦ÄÜ£¬ÎªÁË¿ò¼ÜºÍ·þÎñÆ÷ʵÀýµÄ½¡×³£¬»¹ÐèÒª¼ÓÉÏ´íÎó´¦Àí»úÖÆ¡£

Ä£¿éËÄ£º´íÎó²¶»ñºÍ´íÎó´¦Àí

ҪʵÏÖÒ»¸ö»ù´¡¿ò¼Ü£¬´íÎó´¦ÀíºÍ²¶»ñ±Ø²»¿ÉÉÙ£¬Ò»¸ö½¡×³µÄ¿ò¼Ü£¬±ØÐë±£Ö¤ÔÚ·¢Éú´íÎóµÄʱºò£¬Äܹ»²¶»ñµ½´íÎóºÍÅ׳öµÄÒì³££¬²¢·´À¡³öÀ´£¬½«´íÎóÐÅÏ¢·¢Ë͵½¼à¿ØÏµÍ³ÉϽøÐз´À¡£¬Ä¿Ç°ÎÒÃÇʵÏֵļòÒ×koa¿ò¼Ü»¹Ã»ÓÐÄÜʵÏÖÕâÒ»µã£¬ÎÒÃǽÓϼÓÉÏ´íÎó´¦ÀíºÍ²¶»ñµÄ»úÖÆ¡£

throw new Error('oooops');

»ùÓÚÏÖÔڵĿò¼Ü£¬Èç¹ûÖмä¼þ´úÂëÖгöÏÖÈçÉÏ´íÎóÒì³£Å׳ö£¬ÊDz¶»ñ²»µ½´íÎóµÄ£¬ÕâʱºòÎÒÃÇ¿´Ò»ÏÂapplication.jsÖеÄcallbackº¯ÊýµÄreturn·µ»Ø´úÂ룬ÈçÏ£º

return fn(ctx).then(respond);

¿ÉÒÔ¿´µ½£¬fnÊÇÖмä¼þµÄÖ´Ðк¯Êý£¬Ã¿Ò»¸öÖмä¼þ´úÂë¶¼ÊÇÓÉasync°ü¹ü×ŵ쬶øÇÒÖмä¼þµÄÖ´Ðк¯Êýcompose·µ»ØµÄÒ²ÊÇÒ»¸öasyncº¯Êý£¬ÎÒÃǸù¾Ýes7µÄ¹æ·¶ÖªµÀ£¬async·µ»ØµÄÊÇÒ»¸öpromiseµÄ¶ÔÏóʵÀý£¬ÎÒÃÇÈç¹ûÏëÒª²¶»ñpromiseµÄ´íÎó£¬Ö»ÐèҪʹÓÃpromiseµÄcatch·½·¨£¬¾Í¿ÉÒÔ°ÑËùÓеÄÖмä¼þµÄÒ쳣ȫ²¿²¶»ñµ½£¬Ð޸ĺócallbackµÄ·µ»Ø´úÂëÈçÏ£º

return fn(ctx).then(respond).catch(onerror);

ÏÖÔÚÎÒÃÇÒѾ­ÊµÏÖÁËÖмä¼þµÄ´íÎóÒì³£²¶»ñ£¬µ«ÊÇÎÒÃÇ»¹È±ÉÙ¿ò¼Ü²ã·¢Éú´íÎóµÄ²¶»ñ»úÖÆ£¬ÎÒÃÇÏ£ÍûÎÒÃǵķþÎñÆ÷ʵÀýÄÜÓдíÎóʼþµÄ¼àÌý»úÖÆ£¬Í¨¹ýonµÄ¼àÌýº¯Êý¾ÍÄܶ©ÔĺͼàÌý¿ò¼Ü²ãÃæÉϵĴíÎó£¬ÊµÏÖÕâ¸ö»úÖÆ²»ÄÑ£¬Ê¹ÓÃnodejsÔ­ÉúeventsÄ£¿é¼´¿É£¬eventsÄ£¿é¸øÎÒÃÇÌṩÁËʼþ¼àÌýonº¯ÊýºÍʼþ´¥·¢emitÐÐΪº¯Êý£¬Ò»¸ö·¢Éäʼþ£¬Ò»¸ö¸ºÔð½ÓÊÕʼþ£¬ÎÒÃÇÖ»ÐèÒª½«koaµÄ¹¹Ô캯Êý¼Ì³ÐeventsÄ£¿é¼´¿É£¬¹¹ÔìºóµÄα´úÂëÈçÏ£º

let EventEmitter = require('events');
class Application extends EventEmitter {}

¼Ì³ÐÁËeventsÄ£¿éºó£¬µ±ÎÒÃÇ´´½¨koaʵÀýµÄʱºò£¬¼ÓÉÏon¼àÌýº¯Êý£¬´úÂëÈçÏ£º

let app = new Koa();

app.on('error', err => {
console.log('error happends: ', err.stack);
});

ÕâÑùÎÒÃǾÍʵÏÖÁË¿ò¼Ü²ãÃæÉϵĴíÎóµÄ²¶»ñºÍ¼àÌý»úÖÆÁË¡£×ܽáһϣ¬´íÎó´¦ÀíºÍ²¶»ñ£¬·ÖÖмä¼þµÄ´íÎó´¦Àí²¶»ñºÍ¿ò¼Ü²ãµÄ´íÎó´¦Àí²¶»ñ£¬Öмä¼þµÄ´íÎó´¦ÀíÓÃpromiseµÄcatch£¬¿ò¼Ü²ãÃæµÄ´íÎó´¦ÀíÓÃnodejsµÄÔ­ÉúÄ£¿éevents£¬ÕâÑùÎÒÃǾͿÉÒÔ°ÑÒ»¸ö·þÎñÆ÷ʵÀýÉϵÄËùÓеĴíÎóÒ쳣ȫ²¿²¶»ñµ½ÁË¡£ÖÁ´Ë£¬ÎÒÃǾÍÍêÕûʵÏÖÁËÒ»¸öÇáÁ¿°æµÄkoa¿ò¼ÜÁË¡£

½áβ

ǰΪֹ£¬ÎÒÃÇÒѾ­ÊµÏÖÁËÒ»¸öÇáÁ¿°æµÄkoa¿ò¼ÜÁË£¬ÎÒÃÇʵÏÖÁË·â×°node http server¡¢´´½¨KoaÀ๹Ô캯Êý¡¢¹¹Ôìrequest¡¢response¡¢context¶ÔÏó¡¢Öмä¼þ»úÖÆºÍ°þÑó´ÐÄ£Ð͵ÄʵÏÖ¡¢´íÎó²¶»ñºÍ´íÎó´¦ÀíÕâËĸö´óÄ£¿é£¬Àí½âÁËÕâ¸öÇáÁ¿°ækoaµÄʵÏÖÔ­Àí£¬ÔÙÈ¥¿´koa2µÄÔ´Â룬Äã¾Í»á·¢ÏÖÒ»Çж¼»íÈ»¿ªÀÊ£¬koa2µÄÔ´ÂëÎ޷ǾÍÊÇÔÚÕâ¸öÇáÁ¿°æ»ù´¡ÉϼÓÁ˺ܶ๤¾ßº¯ÊýºÍϸ½ÚµÄ´¦Àí£¬ÏÞÓÚÆª·ù±ÊÕ߾Ͳ»ÔÙÒ»Ò»½éÉÜÁË¡£

Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì

   
10392 ´Îä¯ÀÀ       27