Koa框架前置JS知识
Express:Express是第一代最流行的web框架,它对Node.js的http进行了封装 但是它是'基于ES5'的语法,内部实现异步代码,只有一个方法:'回调'
koa1.x:基于ES6开发,使用generator实现异步,generator实现异步比回调简单不少,但generator的本意并不是异步
koa2.x:基于ES7开发:koa2.x完全使用Promise并配合async实现异步
所以学习Koa需要ES6和ES7的知识
Express、Koa1.x、Koa2.x区别
最大的区别就是内部实现异步的方式不同
- Express使用回调函数实现异步, 容易出现回调地狱问题, 但是语法更老兼容性更好
- Koa1.x使用generator实现异步, 解决了回调地域问题, 但是generator的本意并不是异步
- Koa2.x使用Promise并配合async来实现异步, 解决了回调地域问题, 但是语法太新兼容性不好
第二大的区别就是重量级不同
- Express中内置了很多封装好的功能,而Koa中将这些功能都封装到了独立的模块中,想要使用这些功能必须先安装对应的模块才能使用,所以Koa比Express更轻量级
使用 Babel 实现 Async 方法
要在 node < 7.6 版本的 Koa 中使用 async
方法, 我们推荐使用 babel's require hook
require('babel-register');
// 应用的其余 require 需要被放到 hook 后面
const app = require('./app');
要解析和编译 async 方法, 你至少应该有 transform-async-to-generator 或 transform-async-to-module-method 插件.
例如, 在你的 .babelrc
文件中, 你应该有:
{
"plugins": ["transform-async-to-generator"]
}
你也可以用 env preset 的 target 参数 "node": "current"
替代.
前置知识promise—async+await
Koa的中间件next()
Koa 的中间件是通过 Async/Await 实现的,中间件执行顺序是“洋葱圈”模型。
每一个中间件就相当于洋葱的一层,请求从最外层进去,然后从最里层出来,每个中间件都会执行两次。
next() 的作用是将控制权交给下一个中间件,当一个中间件调用 next() 后,会暂停当前中间件的执行,进入下一个中间件,直到下一个中间件不再执行 next() 时沿路返回,依次将控制权交给上一个中间件。
例如,以下代码定义了三个中间件 one、two、three:
const one = (ctx, next) => {
console.log('>> one');
next();
console.log('<< one');
}
const two = (ctx, next) => {
console.log('>> two');
next();
console.log('<< two');
}
const three = (ctx, next) => {
console.log('>> three');
next();
console.log('<< three');
}
app.use(one);
app.use(two);
app.use(three);
当请求到达时,中间件的执行顺序是:
- one 中间件打印
>> one
,然后调用 next(),进入 two 中间件。 - two 中间件打印
>> two
,然后调用 next(),进入 three 中间件。 - three 中间件打印
>> three
,然后调用 next(),但是没有下一个中间件了,所以返回 three 中间件。 - three 中间件打印
<< three
,然后结束,返回 two 中间件。 - two 中间件打印
<< two
,然后结束,返回 one 中间件。 - one 中间件打印
<< one
,然后结束,响应请求。
所以,最终的输出结果是:
>> one
>> two
>> three
<< three
<< two
<< one
如果 three 中间件不调用 next(),那么它就是最后一个执行的中间件,不会再返回上一层,所以输出结果是:
>> one
>> two
>> three
迭代器和生成器函数
co 库执行 promise 和 generator function
箭头函数 arrow function
const arrow = (param) => {}
const arrow = param => {}
const arrow = param => console.log(param);
异步函数 async function 统一世界
借助 babel 编译 import 与 export
Node 8版本不支持import 与 export语法
解决方法
1.安装babel和插件
npm i babel-cli babel-preset-env -D
2.项目新增配置文件.babelrc
{
"presets": [
[
"env",
{
"targets": {
"node": "current"
}
}
]
]
}
3.在package.json的"script"运行命令配置
"dev": "nodemon -w src -exec \"babel-node src --presets env\""
4.在js使用
import { writeFileSync as wfs } from 'fs'
export使用
export文档:export - JavaScript | MDN (mozilla.org)
生产环境使用 babel 支持 es6-7
1.在package.json的"script"打包构建命令配置,安装rimraf 依赖包,rimraf dist
打包前删除目录
"build": "rimraf dist && babel src -s -D -d dist --presets env"
2.运行编译命令
npm run build
运行打包构建编译后会在生成dist目录