背景
js经常会遇到一些异步任务(需要经过一段时间或当某个时机到达后才能得到的任务)
例如说:
- 使用ajax请求服务器,当服务器完成响应后拿到响应结果
- 监听按钮是否被点击,当按钮点击后拿到某个文本框的值
- 使用setTimeout 等待一段时间,当时间到达后做某些事情
面对这样的场景,JS没有一种标准的模式来进行处理,我们处理这些问题的方式是杂乱的,这就导致了不同的人书写的异步任务代码使用方式不一致。例如说实用第三方库,不知道要传进去多少个参数,或者各种参数放第几位。
ES6异步处理模型
ES6将异步场景分为两个阶段和三种状态
- 两个场景: unsettled (未决) settled (已决)
- 三种状态: pending (挂起) resolved(完成) rejected (失败)
当任务处于未决时
状态一定是pending的,表示任务从开始至拿到结果之间的过程。例如说网络完成了各种配置,发送了请求但还没有收到回复
当任务处于已决时
它只能是resolved和reject两种状态之间的一种。例如说拿到或者没拿到数据--> resolved状态 。网络不通畅 --> rejected状态
我们把从未决推向已决的resolved状态的过程,叫做resolve,从未决推向已决的rejected状态的过程,叫做reject如下图所示
任务已决后(有了结果)
进一步做后续处理,如果任务成功了(resolved),有后续处理,如果任务失败了(rejected),仍可能做后续处理
我们把针对resolved的后续处理称之为thenable,针对rejected的后续处理,称之为catchable
注意事项
- 任务一旦进入已决后,所有企图改变代码任务状态的代码都将失效
- 以下代码可以让任务达到rejected 状态
- 调用reject
- 代码执行报错
- 抛出错误
- 后续处理函数一定是异步函数,并且放在微队列中