Node.js 不正經(jīng)學(xué)習(xí)(第四天 koa.js學(xué)習(xí))

Koa介紹

Koa 是下一代的 Node.js 的 Web 框架辟灰。由 Express 團(tuán)隊(duì)設(shè)計(jì)芥喇。旨在提供一個(gè)更小型凰萨、更富有表現(xiàn)力、更可靠的 Web 應(yīng)用和 API 的開發(fā)基礎(chǔ)胖眷。
Koa可以通過生成器擺脫回調(diào)珊搀,極大地改進(jìn)錯(cuò)誤處理。Koa核心不綁定任何中間件境析,但提供了優(yōu)雅的一組可以快速和愉悅地編寫服務(wù)器應(yīng)用的方法派诬。

安裝

Koa 依賴 node v7.6.0 或 ES2015及更高版本和 async 方法支持.

使用npm安裝

npm i koa

引入

導(dǎo)入koa包默赂,并創(chuàng)建app

/**
 * 引入框架
 */
const Koa = require('koa');
// 創(chuàng)建app對(duì)象
const app = new Koa();

使用

  • 第一個(gè)服務(wù)
// 監(jiān)聽請求并返回響應(yīng)缆八,這里響應(yīng)字符串 "hello , index" 
app.use(async context => {
    context.body = 'hello , index';
});


//啟動(dòng)服務(wù)疾捍,綁定端口
app.listen(3000, () => {
    console.log('服務(wù)啟動(dòng)成功!');
});

use方法

use方法實(shí)際上執(zhí)行順序是從上往下執(zhí)行,但是當(dāng)使用await next(); 之后默認(rèn)會(huì)將use關(guān)聯(lián)的方法壓入棧中冯挎,先壓入得方法后執(zhí)行房官。類似于java中阻塞線程得等待续滋。

  • 可以使用該特性制作N多中間層,進(jìn)行數(shù)據(jù)的處理及業(yè)務(wù)邏輯的封裝疲酌。
/**
 * 攔截請求,打出log日志湿颅。
 * 將該中間層放在棧的最頂層油航。順序await之前從上往下怀浆,阻塞之后從下往上走。
 */
app.use(async (context, next) => {
    // 等待上層執(zhí)行完成
    await next();
    // 獲取本次響應(yīng)的時(shí)間
    const responseTime = context.response.get('X-Response-Time');
    // 打印
    console.log(`${context.method} :: ${responseTime} - ${context.url}`);
});

/**
 * 往請求響應(yīng)頭中寫入響應(yīng)時(shí)間
 */
app.use(async (context, next) => {
    // 請求之前記錄當(dāng)前時(shí)間
    const start = Date.now();
    // 等待上層執(zhí)行完成
    await next();
    // 響應(yīng)之后計(jì)算等待時(shí)間單位毫秒
    const ms = Date.now() - start;
    context.set('X-Response-Time', `${ms}ms`);
});

路由模塊 koa-router

路由模塊使用koa-route,該模塊可以簡單高效的完成接口對(duì)象的抽取及綁定镰踏。
參考

  • 使用npm安裝
npm install koa-router
  • 引入koa-router
/**
 * 引入第三方路由模塊
 */
const _ = require('koa-route');
var router = new _();
  • 使用奠伪,路由集合方式
// 請求路由集合
const pets = {
    '/about': context => {
        context.response.type = 'html';
        context.response.body = '<a href="/">關(guān)于頁面</a>';
    },
    '/login': context => {
        context.response.type = 'html';
        context.response.body = '<div>登錄頁面</div>';
    },
    '/reg': context => {
        context.response.body = '注冊頁面';
    },
    '/mine': context => {
        context.response.type = 'html';
        context.response.body = '<div>個(gè)人中心</div>';
    },
    '/show/:name': (context, name) => {
        context.response.type = 'html';
        context.response.body = '<div>個(gè)人中心 ' + `${name}` + ' </div>';
    }
};
// 添加路由
Object.keys(pets).forEach(function (key) {
    app.use(_.get(key, pets[key]));
});
  • 單個(gè)路由過濾
// 路由home路徑的get請求
router.get('/home', async (ctx, next) => {
    ctx.body = 'we are at home!';
    return next();
}, async (ctx, next) => {
    ctx.body = 'home 2';
});
// 對(duì)應(yīng)HTTP對(duì)應(yīng)的動(dòng)作绊率,all代表所有的請求方式
router
    .get('/', async (ctx, next) => {
        ctx.body = 'Hello World!';
    })
    .post('/users', async (ctx, next) => {

    })
    .put('/users/:id', async (ctx, next) => {

    })
    .del('/users/:id', async (ctx, next) => {

    })
    .all('/users/:id', async (ctx, next) => {

    });

// 將路徑路由添加到app
app
    .use(router.routes())
    .use(router.allowedMethods());

附上Demo代碼

/**
 * 引入框架
 */
const Koa = require('koa');
// 創(chuàng)建app對(duì)象
const app = new Koa();

/**
 * 引入第三方路由模塊
 */
const _ = require('koa-route');
var router = new _();



/**
 * 攔截請求即舌,打出log日志顽聂。
 * 將該中間層放在棧的最頂層盯仪。順序await之前從上往下,阻塞之后從下往上走全景。
 */
app.use(async (context, next) => {
    // 等待上層執(zhí)行完成
    await next();
    // 獲取本次響應(yīng)的時(shí)間
    const responseTime = context.response.get('X-Response-Time');
    // 打印
    console.log(`${context.method} :: ${responseTime} - ${context.url}`);
});

/**
 * 往請求響應(yīng)頭中寫入響應(yīng)時(shí)間
 */
app.use(async (context, next) => {
    // 請求之前記錄當(dāng)前時(shí)間
    const start = Date.now();
    // 等待上層執(zhí)行完成
    await next();
    // 響應(yīng)之后計(jì)算等待時(shí)間單位毫秒
    const ms = Date.now() - start;
    context.set('X-Response-Time', `${ms}ms`);
});


// 請求路由集合
const pets = {
    '/about': context => {
        context.response.type = 'html';
        context.response.body = '<a href="/">關(guān)于頁面</a>';
    },
    '/login': context => {
        context.response.type = 'html';
        context.response.body = '<div>登錄頁面</div>';
    },
    '/reg': context => {
        context.response.body = '注冊頁面';
    },
    '/mine': context => {
        context.response.type = 'html';
        context.response.body = '<div>個(gè)人中心</div>';
    },
    '/show/:name': (context, name) => {
        context.response.type = 'html';
        context.response.body = '<div>個(gè)人中心 ' + `${name}` + ' </div>';
    }
};
// 添加路由
Object.keys(pets).forEach(function (key) {
    app.use(_.get(key, pets[key]));
});
// 路由home路徑的get請求
router.get('/home', async (ctx, next) => {
    ctx.body = 'we are at home!';
    return next();
}, async (ctx, next) => {
    ctx.body = 'home 2';
});
// 對(duì)應(yīng)HTTP對(duì)應(yīng)的動(dòng)作滞伟,all代表所有的請求方式
router
    .get('/', async (ctx, next) => {
        ctx.body = 'Hello World!';
    })
    .post('/users', async (ctx, next) => {

    })
    .put('/users/:id', async (ctx, next) => {

    })
    .del('/users/:id', async (ctx, next) => {

    })
    .all('/users/:id', async (ctx, next) => {

    });

// 將路徑路由添加到app
app
    .use(router.routes())
    .use(router.allowedMethods());

app.use(async context => {
    context.body = 'hello , index';
});



app.listen(3000, () => {
    console.log('服務(wù)啟動(dòng)成功!');
});
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末梆奈,一起剝皮案震驚了整個(gè)濱河市亩钟,隨后出現(xiàn)的幾起案子鳖轰,更是在濱河造成了極大的恐慌,老刑警劉巖蕴侣,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異鹦马,居然都是意外死亡忆肾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門旭从,熙熙樓的掌柜王于貴愁眉苦臉地迎上來和悦,“玉大人,你說我怎么就攤上這事鸽素♀珊觯” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵坝冕,是天一觀的道長瓦呼。 經(jīng)常有香客問我,道長磨澡,這世上最難降的妖魔是什么钱贯? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任侦另,我火速辦了婚禮,結(jié)果婚禮上弃锐,老公的妹妹穿的比我還像新娘霹菊。我一直安慰自己支竹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布饶碘。 她就那樣靜靜地躺著馒吴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪豪治。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天烦衣,我揣著相機(jī)與錄音花吟,去河邊找鬼。 笑死涣脚,一個(gè)胖子當(dāng)著我的面吹牛寥茫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播芭梯,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼玖喘,長吁一口氣:“原來是場噩夢啊……” “哼蘑志!你這毒婦竟也來了累奈?” 一聲冷哼從身側(cè)響起澎媒,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤戒努,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后镐躲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體储玫,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年萤皂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了撒穷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡裆熙,死狀恐怖桥滨,靈堂內(nèi)的尸體忽然破棺而出窝爪,到底是詐尸還是另有隱情,我是刑警寧澤齐媒,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布蒲每,位于F島的核電站,受9級(jí)特大地震影響喻括,放射性物質(zhì)發(fā)生泄漏邀杏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望腕侄。 院中可真熱鬧微姊,春花似錦兢交、人聲如沸配喳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赞别,卻和暖如春仿滔,著一層夾襖步出監(jiān)牢的瞬間鞠绰,已是汗流浹背蜈膨。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留灶壶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓箫荡,卻偏偏與公主長得像羔挡,于是被迫代替她去往敵國和親绞灼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子印叁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容