- 那么什么是异步呢?
比如说我现在想完成一个任务,但是这个任务不是立刻能完成的,需要经过一段时间后 才能有一个结果,
在这个任务完成之前我是不知道这个任务的最终结果的,我需要等到任务完成的时候才能确切知晓结果。这就是异步的一个概念了。
- 异步的使用场景 以及 与 Promise 方式的比较
例如我们处理 setTimeout 的时候是通过回调来处理的(就是任务完成再去告知结果)
我们知道,做回调的时候,层级少不会影响太大,
但如果现在有一个事件a,a会在一分钟之后响应,a也是个异步,a在一分钟后才会知道b,b会在一分钟后知道c.......
如果层数很深,那么这个回调写起来就会变得痛苦无比,所以后来才有了 Promise 对象的写法(Promise 对象通过 .then.then去做)
Promise 对象也需要手动的去调用,最后导致调用也会很长,
于是出现了 async 和 await 的方法
- async 和 await使用方法
这里我们回看一下,Koa 初始项目的接口文件
下面我们来分析一个例子(伪代码部分)
这里的 a 结果需要等待 await A 拿到结果后赋给 a ,
才会往下执行b,b也是一样,再到最后c.都是依次执行完再往下执行的
这样通俗来讲,就是用同步的写法,来完成了异步的过程
1 router .get('/', async (ctx, next) => { 2 gLoba l. console. Log( ' index2' )
//-----------伪代码-------------- 3 const a = await A; 4 const b = await B; 5 const C = await C;
//-----------伪代码--------------
6 await ctx. render( ' index', { 7 title: 'Hello Koa 2! ' 8
})
9 })
我们这里在列举一个实例
我们在这个初始化项目接口里写一个异步测试接口,然后分析下执行顺序,代码如下
//异步测试接口 //await后面跟的是一个Promise对象,如果不写也会默认转换补上 //这是个异步获取 a,没有再用回调的方法来实现 //代码执行顺序分析 // 一、接口被调用后输出“开始”,给 变量a赋值 // 二、向页面输出文字 // 三、发现变量a的值需要请求等待回应后反馈给页面
//------ 一、----- router.get('/testAsync',async (ctx)=>{ global.console.log('开始',new Date().getTime()) const a = await new Promise((resolve,reject)=>{ //这里设置一个定时输出来模拟数据请求或者事务处理时间 //加了 await 后就会等到获取到a的值后再反馈到页面 setTimeout(function(){ global.console.log('异步获取 a',new Date().getTime())
//-------- 三 ---------- resolve('a') //返回最终的a },1000); })
//------ 二、----- ctx.body={ a } })
测试接口
如果我们加大超时时间,这个停顿感会更明显