npm i koa
複製代碼
const Koa = require('koa');
const app = new Koa();
app.listen(3000);
## koa中的異步
複製代碼
Koa 提供一個 Context 對象,表示一次對話的上下文(能夠理解爲上(request)下(response)溝通的環境)。
經過加工這個對象,就能夠控制返回給用戶的內容。css
const Koa = require('koa');//引進koa
const app = new Koa(); //構建一個實例
const main = ctx => {
ctx.response.body = 'Hello World'; // ctx.response
};
app.use(main);
app.listen(3000);
複製代碼
***爲了便於訪問和調用,許多 context 的屬性和方法,代理了 ctx.request 和 ctx.response 所對應的等價方法, 好比說 ctx.type 和 ctx.length 代理了 response 對象中對應的方法,ctx.path 和 ctx.method 代理了 request 對象中對應的方法。html
1.koa經過next()方法調用下一個中間件。前端
let Koa = require('koa');
// app 是監聽函數
let app = new Koa();
// koa裏面 就兩個經常使用的方法 listen use
app.use(function(ctx,next){
ctx.body = {'name':'zfpx'}
throw new Error('出錯了');//註釋掉就會執行next(),訪問3000獲得name:xiaoming,沒有註釋就會被錯誤捕獲。
next();
});
app.use(function(ctx,next){
ctx.body = {'name':'xiaoming'}
});
// 監聽錯誤捕獲
app.on('error',function(err){
console.log(err);
});
// 調用next就會執行下一個中間件,ctx.body 能夠設置屢次,以最後的爲主,等待中間件所有執行完 會將ctx.body結果響應給客戶端
app.listen(3000);
複製代碼
看下面代碼 寫出執行順序node
let Koa = require('Koa');
let app = new Koa();
app.use((ctx,next)=>{
console.log(1);
return next(); // 咱們在這調用next方法
console.log(2)
});
app.use((ctx,next)=>{
console.log(3);
next();
console.log(4)
})
app.listen(3000);
複製代碼
答案是1-3-4 上面的執行代碼等同於下面的。是否是一目瞭然了。return後面的語句不執行因此2沒有打印git
app.use((ctx,next)=>{
console.log(1);
return app.use((ctx,next)=>{
console.log(3);
next();
console.log(4)
}); // 咱們在這調用next方法
console.log(2)
});
複製代碼
2.koa的異步 有的時候咱們須要一箇中間件須要在另一個異步函數執行完返回結果後執行。這個時候咱們就須要異步koa了。 在koa中會把異步的方法所有封裝成promisegithub
app.use((ctx,next)=>{
console.log(3);
setTimeout(()=>{
console.log(4)
},3000)
console.log(5) //這個代碼並不會等待定時器執行完在執行。
next()
})
// 3-5-4
咱們想要的效果是3-4-5。這個時候就須要異步了。
在koa中
// 支持異步操做
// 在koa中會把異步的方法所有封裝成promise
複製代碼
function log(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('log');
resolve();
},3000)
})
}
//先執行第一個中間件函數 此時在這個函數中調用next函數
// 就執行下一個函數(這個函數裏面有異步操做)
// 第一個中間件函數應該等待着第二個中間件函數執行,否則就在第二個中間件await的時候直接執行下一部
// 在內部會把這些中間件包裝成promise
app.use(async (ctx,next)=>{
console.log(1);
await next(); // 咱們在這調用next方法
console.log(2);
});
app.use(async (ctx,next)=>{
console.log(3);
await log(); //等待log執行
await next();
console.log(4)
})
複製代碼
Koa 的最大特點,也是最重要的一個設計,就是中間件(middleware) koa經常使用的中間件有
koa-bodyparser /koa.js並無內置Request Body的解析器,當咱們須要解析請求體時須要加載額外的中間件,官方提供的koa-bodyparser是個很不錯的選擇,支持x-www-form-urlencoded, application/json等格式的請求體,但不支持form-data的請求體,須要藉助 formidable 這個庫,也能夠直接使用 koa-body 或 koa-better-body
npm
koa-better-body /處理數據使用
koa-static Node.js除了處理動態請求,也能夠用做相似Nginx的靜態文件服務,在本地開發時特別方便,可用於加載前端文件或後端Fake數據,可結合 koa-compress 和 koa-mount 使用。/
koa-views koa-views對須要進行視圖模板渲染的應用是個不可缺乏的中間件,支持ejs, nunjucks等衆多模板引擎。/
koa-session Node.js除了處理動態請求,也能夠用做相似Nginx的靜態文件服務,在本地開發時特別方便,可用於加載前端文件或後端Fake數據,可結合 koa-compress 和 koa-mount 使用。/
koa-router 路由是Web框架必不可少的基礎功能,koa.js爲了保持自身的精簡,並無像Express.js自帶了路由功能,所以koa-router作了很好的補充,做爲koa星數最多的中間件,koa-router提供了全面的路由功能,好比相似Express的app.get/post/put的寫法,URL命名參數、路由命名、支持加載多箇中間件、嵌套路由等。其餘可選路由中間件:koa-route, koa-joi-router, koa-trie-router /
json
1.中間件使用
let bodyParser = require('koa-bodyparser') app.use(bodyParser())
2.原理簡單實現後端
let Koa = require('koa');
let app = new Koa();
app.use(async(ctx, next) => {
if (ctx.path === '/' && ctx.method === 'GET') {// get請求3000
ctx.set('Content-Type', 'text/html;charset=utf8');
ctx.body = `
<form action="/" method="post" >
<input type="text" name="username" autoComplete="off">
<input type="text" name="password" autoComplete="off">
<input type="submit" >
</form>
`
} else {
next();// 提交表單後變成post請求走到post請求的中間件裏
}
});
function bodyParser(ctx) {
return new Promise((resolve, reject) => {
let arr = [];
ctx.req.on('data', function(data) {
arr.push(data);
});
ctx.req.on('end', function() {
let body = Buffer.concat(arr).toString();
resolve(body)
})
})
}
app.use(async(ctx, next) => {
if (ctx.method === 'POST' && ctx.path === '/') {
// 獲取表單提交過來的數據
ctx.body = await bodyParser(ctx);
//將post的請求data數據賦給ctx.
}
})
app.listen(3000);
複製代碼