4.1 koa的由來

本節(jié)我們將簡單介紹一下 koa。

nodejs是什么?

Node.js是一個創(chuàng)建于 2009年的Javascript運(yùn)行環(huán)境。它使用了一個事件驅(qū)動、非阻塞式 I/O 的模型,基于回調(diào)實現(xiàn)的異步編程,使其輕量又高效。

例如,我們可以一邊讀取文件,一邊執(zhí)行其他命令,在文件讀取完成后,我們將文件內(nèi)容作為回調(diào)函數(shù)的參數(shù)返回。這樣在執(zhí)行代碼時就沒有阻塞或等待文件 I/O 操作。

這就大大提高了 Node.js 的性能,可以處理大量的并發(fā)請求,因此,Node 主要用在開發(fā) Web 應(yīng)用。

使用原生nodejs提供web服務(wù)

要在nodejs中提供web服務(wù),我們需要引入 nodejs 的Http模塊:require('http'), 然后調(diào)用createServer方法,傳入一個函數(shù)作為參數(shù)即可:

const Server = http.createServer((req, res) => {
  res.writeHead(200,{'Content-Type': 'application/json;charset=utf-8;'});
  res.write('{text: "寫代碼很快樂啊!"}');
  res.end();
}).listen(8888);

可以看到,代碼可讀性不是很好,開發(fā)也不是很便利,于是就有了 Express 這個第一代最流行的web框架。

express 框架

我們看看,使用express, 怎么實現(xiàn)一個最簡單的入門網(wǎng)站:

var express = require('express');
var app = express();
app.get('/', function (req, res) {
    res.send('寫代碼很快樂!');
});
app.listen(8888);

可以看到,代碼精簡了很多,雖然express的API很簡單,但是它是基于ES5的語法,要實現(xiàn)異步代碼,只有一個方法:回調(diào)。如果異步嵌套層次過多,代碼寫起來就非常難看,比如讀取一個文件成功后再讀取一個文件:

app.get('/file', function (req, res) {
    fs.readFile('/file1', function (err, data) {
        if (err) { res.status(500).send('讀取文件1失敗'); }
        fs.readFile('/file2', function (err, data) {
            if (err) {  res.status(500).send('讀取文件2失敗'); }
            res.type('text/plain');
            res.send(data);
        });
    });
});

雖然可以用async這樣的庫來組織異步代碼,但是用回調(diào)寫異步實在是太痛苦了,特別是異步嵌套多的時候,這就是JS遠(yuǎn)古時期的 回調(diào)地獄!

koa 1.x的到來

隨著ES6在新版Node.js獲得支持ES6,express的團(tuán)隊基于ES6的generator推出了koa這個 web 框架。和express相比,koa 1.0使用generator實現(xiàn)異步,比如實現(xiàn)上面同樣的功能,代碼如下:

var koa = require('koa');
var app = koa();

app.use('/file', function *() {
    yield readFile1();
    var data = yield readFile2();
    this.body = data;
});
app.listen(8888);

可以看到,用generator實現(xiàn)異步比回調(diào)簡單了不少,但是generator的本意并不是異步。Promise才是為異步設(shè)計的,但是Promise的寫法很復(fù)雜。為了簡化異步代碼,ES7引入了新的關(guān)鍵字async和await,可以輕松地把一個function變?yōu)楫惒侥J剑?/p>

async function () {
    var data = await fs.read('/file1');
}

最新的koa 2.x的到來

koa團(tuán)隊并沒有止步于koa 1.0,他們非常超前地基于ES7開發(fā)了koa2,和koa 1相比,koa2完全使用Promise并配合async來實現(xiàn)異步。

app.use(async (ctx, next) => {
    await next();
    var data = await readFile();
    ctx.response.type = 'text/plain';
    ctx.response.body = data;
});

通過以上分享,大家可以看到,我們項目使用koa2,是按照node->express->koa1-<koa2 一步步隨著新的JS規(guī)范通過并獲得支持的發(fā)展而來的,出現(xiàn)的主要原因就是為了在node開發(fā)中優(yōu)雅的寫異步代碼。

express, koa1和koa2的區(qū)別

koa vs express

  • 相同點

    • 構(gòu)建 web 應(yīng)用的 node 框架
    • 總體來看語法差別不大,比如都是引入后框架后實例后,中間件處理以及監(jiān)聽端口;
    • 都是同一個團(tuán)隊開發(fā)維護(hù)的
  • 區(qū)別

    • express: 框架內(nèi)容更豐富,有更大的社區(qū),歷史更悠久,文檔更豐富,用戶群更大,支持 jade 等前端模板語言,express沒有統(tǒng)一的錯誤處理,而koa有默認(rèn)的錯誤處理方式。
    • koa: 更小、更富有表現(xiàn)力、更健壯,Koa 支持 es6 語法,Koa 在內(nèi)核方法中不綁定任何中間件,不提供路由功能和某些工具,摒棄了的回調(diào),采用 generator 或 promise的方式,在 Context中,Koa 對 request 和 response 進(jìn)行了封裝,使用方式也相應(yīng)改變,如返回簡單內(nèi)容,在koa: this.body = ‘hello world’,而在express: res.send(‘hello world’)。

koa1 vs koa2

  • 中間件的使用: koa1依賴 co 并采用 generator 函數(shù),在函數(shù)內(nèi)使用 yield 語句,而koa2增加了箭頭函數(shù),移除了 co 依賴,使用 Promise,因此可以結(jié)合 async,await 使用;
  • context 對象的獲?。簁oa1為this 對象,this.req, this.res;koa2: cxt 參數(shù),cxt.req, cxt.res。

了解了koa的背景知識后,下一節(jié)我們將簡單分析其源碼啦!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 跟好朋友打賭,我要來個技術(shù)文章日更。于是,我跑到到群里喊了句,我要日更。沒想到,得到的是大家的支持與鼓勵。感...
    白昔月閱讀 25,906評論 26 108
  • 前言 Koa 是運(yùn)行在 Node.js 中的 web 服務(wù)框架,小而美。 Koa2 是 Koa 框架的最新版本,K...
    let_Scott閱讀 5,892評論 2 28
  • 第四期進(jìn)階班打卡已經(jīng)進(jìn)行5天了,沒想到這期打卡的內(nèi)容進(jìn)行了迭代更新,這一期的打卡內(nèi)容是我參加語言美學(xué)以來體驗最好的...
    微笑你好閱讀 203評論 0 0
  • 花開了,在一個美麗的晨曦中, 草綠了,在一個昏暗的夜晚里。 花說‘‘你看我多么嬌艷!’’ 草笑而不答。 蜜蜂來了,...
    夏茗墨閱讀 384評論 1 1
  • 什么是動詞,什么是形容詞,什么是名詞?怎樣記住原始詞,怎么以一個實例來記住變形以及變形后的詞義 音譯法 拼音法 字...

友情鏈接更多精彩內(nèi)容