撩课-Web架构师养成系列-异步编程

前言

Web架构师养成系列共15篇,每周更新一篇,主要分享、探讨目前大前端领域(前端、后端、移动端)企业中正在用的各种成熟的、新的技术。部分文章也会分析一些框架的底层实现,让我们做到知其然知其所以然。

---本篇文章阅读需要时长:约20分钟---

一、先了解异步?

关于"异步",我们可以这么理解: 一个任务拆分成两段,先执行第一段,然后转而执行其他任务,等到某个时间点,再回过头执行第二段。

比如,你要做土豆炖牛肉,当开始煮牛肉的时候发现土豆没了,可以先让牛肉煮着,然后去买土豆、洗好、切好,再把土豆放到锅里一起煮。

土豆炖牛肉

这种不连续的执行,就叫做异步。相应地,如果是连续的执行,那么就叫做同步。

1.1 JS中常见的异步编程方式?

异步编程的目标就是让代码的执行更加类似于同步编程,开发中比较常用的方式主要包括:

在ES6之前,我们更多地是使用回调函数来实现异步编程。

1.2 认识回调函数

回调函数就是把任务拆解成两部分,把任务的第二部份单独写在一个函数里面,等到执行完其它任务重新执行这个任务的时候,就直接调用这个函数,从而达到异步效果。

案例如下:

运行结果

虽然回调函数能够实现异步,但是回调函数存在以下问题:

回调地狱(图片来源于网络)

二、异步改进方案-Promise

2.1 什么是Promise?

promise,承诺。在代码中我们可以这么理解:此处我先许下个承诺,过了一定时间后我带给你一个结果。

那么,在这一段时间中做什么?

我们可以进行异步操作;

比如请求网络数据、耗时运算、读写本地文件等

2.2 Promise的三种状态?

比如:你发邮件给老板说要加工资,这时候你就要"等待"他的邮件回复,他可以立马给你回复,如果同意了,表示"成功";如果不同意,表示"失败",当然他也可以一直不同意;但是这期间不影响你做其它事情。

在实际开发中,我们可以通过then 方法,来指定Promise 对象的状态改变时确定执行的操作,resolve 时执行第一个函数(onFulfilled),reject 时执行第二个函数(onRejected)。

来,一起认识下promise的几种操作方式和常用方法:

构建Promise

promise也可以代表未来的一个值

一个promise实例可以多次调用then,当成功后会将结果依次执行。

promise也可以代表一个不用返回的值

Promise.resolve

返回一个Promise实例,这个实例处于resolve状态。

Promise.reject

返回一个Promise实例,这个实例处于reject状态。

Promise.race

该方法用于接收一个数组,数组内都是Promise实例,返回一个Promise实例,这个Promise实例的状态转移取决于参数的Promise实例的状态变化。

当参数中任何一个实例处于resolve状态时,返回的Promise实例会变为resolve状态。如果参数中任意一个实例处于reject状态,返回的Promise实例变为reject状态。

2.3 案例实操

我们再用promise实现上面发邮件加工资的案例:

情况一 :

在一定时间后(假设5s后),老板回复了邮件,可以是以下两种情况:

情况二 :

公司账户已经没钱,没法加工资了,表现形式如下:

我们可以采用then的第二个参数捕获reject返回结果或者捕获失败,当然也可以通过函数进行捕获。

三、promise可以解决回调函数带来的问题

前面的案例描述已经验证了promise支持catch,此外,通过promise也能够返回结果给外部。我们再一起看看promise如何解决回调地狱和同步异步结果。

3.1 解决回调地狱

案例场景:在中存放正的路径,在中存放正的路径, 我们要取出里面的内容。

回调函数实现:

通过promise解决回调地狱:

3.2 同一时刻同步所有异步产生的结果

该场景在实际开发中有很多应用场景,比如:我们要提交一个操作时,需要结合之前的两个异步请求的结果才能进行。

再比如:你要进行下一个运算时,需要前面两个异步运算的结果才能进行。我们还是通过读取文件的案例来进行举例。

常规方式实现:

这样的方式虽然解决了问题,但是你不知道最终结果是在哪个异步函数中输出,而且你需要在所有的异步函数中都去调用打印方法。

promise方式大大简化:

借助promise.all()方法,不管哪个promise谁先完成,该方法会按照数组里面的顺序将结果返回。

后续

借助Promise已经可以帮助我们很好解决异步编程的问题,但还不是那么的行云流水、一气呵成,我们更希望编写异步代码能够像写同步代码一样直观、简单。

在下一篇我们会讲些更好、更灵活的异步编程方案,敬请期待。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181206A0CEVM00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券