Promise、async、await

我们都知道,JavaScript是一门单线程的编程语言,但是在单线程中进行异步编程,可以有很多多线程所不具备的优点。由于所有的操作都运行在同一个线程中,因此我们无需考虑线程同步资源竞争的问题。并且可以从源头上避免线程的切换,从而降低线程自身的开销。

即使JS是单线程,也依旧可以执行异步任务,方式很简单,先让异步任务线程去执行异步任务,待异步任务执行完毕后,再将对应的回调交给事件触发线程去维护,再由事件触发线程依次地将这些异步任务交给JS引擎线程来执行即可。

有这样一种特出的场景,会使得在单线程的JS中,可读性变得极差,就是在异步任务中添加异步任务。例如在在定时器内添加定时器,代码就是这样的:

Promise、async、await

 如果我们还需要在内部嵌套很多定时器,随即就会产生一个回调地狱,这种代码的可读性非常差,以至于我们在分析这样的代码时,需要额外花费很多的事件去分析代码的逻辑。

借助Promise,通过它的链式调用,就可以避免代码的层层嵌套。

使用方法很简单,就比如下面这个fetch方法

Promise、async、await

fetch会返回一个Promise对象,我们只需要通过then方法,就可以执行 “异步任务执行完毕后” 想要进行的动作

如果我们在这个异步任务完成后,还需要执行异步任务,就只需要将这个异步任务放入.then中,接着通过下一个.then控制异步任务完成后所需要执行的代码。

 这样就极大地增加了代码可读性。

 当然这个过程也可能产生错误,只需要在最后调用catch方法,它会在任意一个任务产生错误时被触发,那么接下来的.then方法就不再会被执行。

Promise、async、await

在整个调用链的末尾,还可以增加一个finally方法,来做一些清理工作。例如我们用到了加载动画,就可以在finally中去关闭该任务。

Promise、async、await

async、await

它们是基于Promise之上的一个语法糖

Promise、async、await await可以暂停函数的执行,等待异步异步任务完成,获取到异步任务的结果。但在等待的过程中,同样可以运行其他的代码。

这是因为,await底层是基于Promise事件循环机制实现的。

注意:

要合理正确的使用await,例如下面这个场景:

Promise、async、await

如果我们分别去await这两个操作,虽然不存在逻辑错误,但是本来应该是并行执行两个fetch,却变成了一个任务执行完之后,才能去执行第二个任务。 

正确的做法,应该是将这两个Promise任务先用Promise.all组合起来,再去使用await

Promise、async、await

 2. 如果我们需要在循环中执行异步操作,是不能够直接使用forEach、map这一类方法的,如果在这种场景下使用,await就不再起作用,会被立刻返回

Promise、async、await

 可以使用最基本的遍历方法,例如for...of

Promise、async、await

3. 我们不能在全局或普通函数中使用await,如果真的想要去使用,就需要将任务包装在一个IIFE

Promise、async、await

上一篇:async+await配合,使异步函数同步化,解决地狱回调(可适用于vue请求)


下一篇:基于mirai的pythonqq机器人(graia的使用)