koa初体验

出于对koa的好奇,于是想要了解下。

koa 是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架。

如果说koa是下一代web开发框架,那么上一代毫无疑问就是express了,其实用哪个都无所谓啦,只要自己用的顺手就好。反正我哪个都用不到,至少目前是的,哈哈。

开始

新建一个文件夹koaDemo,其内执行:

1
2
3
npm init -y

npm install koa

我们讨论的是koa2。而koa默认安装的就是2的版本,所以无需指定为koa2。

用koa来输出“hello world”,新建一个文件server.js,输入以下内容:

1
2
3
4
5
6
7
8
const Koa = require('koa')
const app = new Koa()

app.use(async ctx => {
ctx.body = 'hello world'
})

app.listen(3000)

node server.js执行文件,此时打开浏览器,访问:http://localhost:3000/,熟悉的hello world就显示出来啦。

可以看到,koa真的很精简,短短几行就能启动一个服务,虽然这些express都能办到,但是koa肯定也是有它的独到之处的。其中之一就是使用 async+await 处理异步,上面代码中已用到了async,接下来就介绍下async和await。

async与await

koa的一大优点就是No Callback,很多人使用koa也是因为这个。没有回调得力于async和await的使用,关于它们的概念我也讲不好,网上有很多文档可以参考,你只需要知道它可以解决回调地狱的问题,使异步操作更优雅。具体怎么个优雅法,我们来慢慢看。

回调函数处理异步

在最初的时候,我们使用回调函数来处理异步,来看个例子:

1
2
3
4
5
6
7
8
9
10
11
12
function test() {
setTimeout(()=>{
console.log('执行了')
}, 2000)
}

test()
console.log('结束')

// 执行结果
结束
执行了

上面代码的执行结果显然不符合预期的,所以我们需要借助回调函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function test(fn) {
setTimeout(()=>{
console.log('执行了')
fn()
}, 2000)
}

test(()=>{
console.log('结束')
})

// 执行结果
执行了
结束

显然,这才是我们想要的结果,回调虽然看起来很简单,但是当业务逻辑多起来时,容易形成回调地狱,比如:

1
2
3
4
5
6
7
ajax(()=>{
ajax(()=>{
ajax(()=>{
// ...
})
})
})

三层,不能再多了!三层都快受不了了,更别说更复杂的了,当维护这样的代码时,是真的难受。所以后来es6给了一个好的解决方法,那就是promise。

promise

关于promise诞生的前前后后我就不介绍了,因为我也不太熟悉啊,不过它的使用方法我们还是要掌握的,推荐阮一峰老师的es6教程,传送门:promise

来写一个promise的例子,假设三个异步操作,依次执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function delay(val){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(val)
},2000)
})
}

delay('第一步执行')
.then((val)=>{
console.log(val)
return delay('第二步执行')
})
.then((val)=>{
console.log(val)
return delay('第三步执行')
})
.then((val)=>{
console.log(val)
})

// 结果
第一步执行
第二步执行
第三步执行

promise的使用,解决了一层层回调嵌套的窘境,这很大程度上解决了回调地狱的问题,清晰的代码结构也容易维护。

promise很好用,但是代码量还是有点的,如果可以,何不试试async+await呢?

async+await

虽然我也想把这两个概念讲的很明白,但是我不能啊,网上有大佬讲的很清楚,在这我就简单说下。

你需要知道的是,async用来定义一个异步函数,它总会返回异步对象,即promise,而await必须在async内部使用,用来处理异步结果。

说不如做,就拿上面的例子来试下async的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function delay(val){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(val)
},2000)
})
}

async function start(){
let result1 = await delay('第一次执行')
console.log(result1)

let result2 = await delay('第二次执行')
console.log(result2)

let result3 = await delay('第三次执行')
console.log(result3)
}
start()

// 结果
第一步执行
第二步执行
第三步执行

如上代码,同步的方式写异步,再也看不到回调了,是不是很爽。在koa中,重点使用async+await的方式,所以不懂得童鞋还得加把劲啊。即使不用koa,但这么炫酷的方法你确定不试试?

总结

写完后才发现,我不是介绍koa的,反而介绍了async,虽然没讲得明白。麻雀虽小五脏俱全,koa的更多使用,下次再说咯。