Koa
next generation web framework for node.js
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);
Generator
Thunk
Co
Aysnc/Await
Node.js
// 耗費時間M
getData('from_db');
// 耗費時間N
getData('from_remote_api', function (result) {});
Node.js 本身是 Javascript
單執行緒遇到阻塞I/O
提供異步編程
Node.js
異步編程問題
fs.readFile('file1.txt', 'utf8', function (err, txt) {
if (err) {
throw err;
}
fs.readFile(txt, 'utf8', function (err, content) {
if (err) {
throw err;
}
console.log(content);
});
});
fs.readFile('file1.txt', 'utf8', function (err, txt) {
if (err) {
throw err;
}
console.log(txt);
});
fs.readFile('file2.txt', 'utf8', function (err, content) {
if (err) {
throw err;
}
console.log(content);
});
如何避免 Callback Hell?
- 自定義
- Promise/Deffered
- Higher Order Function
fs.readdir(path.join(__dirname, './index.js'), (err, files) => {
files.foreach((filename, index) => {
fs.readFile((filename, 'utf-8', (err, file) => {
...
}))
})
})
使用高階函數解法
var pending = (function () {
var count = 0;
return function (callback) {
count++;
return function () {
count--;
if (count === 0) {
callback();
}
};
};
}());
var done = pending(function () {
console.log('all is over');
});
fs.readFile('file1.txt', 'utf8', done());
fs.readFile('file2.txt', 'utf8', done());
https://repl.it/repls/JampackedDarkmagentaClimate
Generator Intro
- 在 Generator 出現以前,函數只有 use 跟 not use 的情況
- 基本定義
- 使用 yield 的暫停效果
- 查看 next 結果挾帶的狀態
- 可利用 next 傳遞參數,傳回 yield 前面的變數
Thunk
- 編譯器的求值策略 - 傳值調用 vs 傳名調用
var x = 1;
function f(m) {
return m * 2;
}
f(x + 5);
// 傳值調用
// 先計算
f(x+5)
f(6)
// 傳名應用
// 只在用到時才計算
f(x + 5)
f(x + 5 * 2)
// 哪一個好?
// 傳值應用比較簡單,但以下範例就會做不必要求值
function f(a, b){
return b;
}
f(3 * x * x - 2 * x - 1, x);
Thunk 定義
- 傳名調用 - 將參數放到臨時函數裡,再將臨時函數放到函數裡
- 此臨時函數就是 - Thunk
function f(m){
return m * 2;
}
f(x + 5);
// 等同于
var thunk = function () {
return x + 5;
};
function f(thunk){
return thunk() * 2;
}
Javascript 裡的 Thunk
- 將多參數函數轉為單參數函式,且參數只接受 callback
// 正常版本的readFile(多參數本)
fs.readFile(fileName, callback);
// Thunk版本的readFile(單参数版本)
var readFileThunk = Thunk(fileName);
readFileThunk(callback);
var Thunk = function (fileName){
return function (callback){
return fs.readFile(fileName, callback);
};
};
Thunk + Generator
Co
- 使用 Promise
- 不需編寫 Generator 執行器
Flow 並發執行
Aysnc / Await
- generator + yield 的語法糖
-
async 函数就是將 Generator 函数的星號(*)替换成 async,将 yield 替换成 await,僅此而已
-
就字面上意思也更好理解
說好的洋蔥呢
講到這大家都累了...
一行入魂,ㄜ不是,一張 Gif 解釋洋蔥蔥
Koa 洋蔥
By Stanney Yen
Koa 洋蔥
- 255