上一篇中提到了回调地狱的问题,ES6为了解决多层回调,提高代码的可阅读性,提出了一套异步的通用模型,这一部分对理解promise很重要
1.两个阶段
该模型中,将一件可能发生异步操作的事情分为两个阶段:unsettled 和 settled
- unsettled:未解决阶段,表示事情还在进行前期的处理,并没有发生通向结果的那件事
- settled:已解决阶段,事情已经有了一个结果,不管这个结果是什么,整件事情无法逆转
【注】事情总是从为解决阶段逐步发展到以解决阶段的,并且未解决阶段拥有控制何时通向已解决阶段
举个例子来说明一下,某天小明去超市购物,选好商品以后,小明来到收银台,一边掏出手机准备支付,一边排队等待结账(异步),此时事件为未解决阶段,且等待的时间控制着事件何时进入已解决阶段。当小明之前的客人均结账后,轮到小明结账,此时会出现几种结果:1)小明的余额充足,成功结账,小明美滋滋;2)小明的余额不足,尴了个尬,小明表示我原本很快乐,是没钱害了我;3)收银台的机器出现问题,小明不能买单(此时系统报错,相当于将事件推向了rejected,后面详细讲)。接下来康康小明shopping的代码吧
//小明去购物
function goShopping() {
console.log('小明挑选商品');
console.log('小明等待结账');
setTimeout(() => {
console.log('小明开始结账');
if (Math.random()>0.5) { //表示小明的余额足够结账
console.log('小明的余额充足,成功结账,小明表示美滋滋');
} else {
console.log('小明的余额不足,尴了个尬,小明表示我原本很快乐,是没钱害了我');
}
}, 1000);
}
goShopping();
2.三种状态
ES6将事情划分为三种状态,pending,resolved,rejected
- pending:挂起,处于未解决阶段,表示这件事情的最终结果还没有出来
- resolved:已处理,以解决阶段的一种状态,表示整件事情已经出现结果,并且是一个可以按照正常逻辑进行下去的结果
- rejected:已拒绝,已解决阶段的一种状态,表示整件事情已经出现了结果,并且是一个无法按照正常逻辑进行下去的结果,通常用于表示有一个错误
【注】
1)未解决阶段可以决定事情最终的状态;
2)我们把事情变为resolved状态的过程叫做resolve,推向该状态时可能会传递一些数据;
3)我们把事情变为rejected状态的过程叫做reject,推向该状态时可能会传递一些数据,通常为错误信息;
这里我们再来参照小明购物的例子,从小明开始购物开始,这件事情是一个未解决阶段,是一个挂起过程,并且随着小明挑选商品购物等等,开始逐步发展向已解决阶段。当轮到小明买单时,会出现三种情况:余额充足成功支付,余额不足无法支付,系统报错未建立连接。根据三种情况我们分析,前两种属于按照正常逻辑处理,即resolved状态,而第三种属于未按照正常逻辑处理,系统拒绝给小明结账,即rejected状态。这里需要注意的点是,由于余额不足导致的未成功支付不属于rejected,因为该情况是按照正常的逻辑执行完的。
【注】无论是阶段还是状态,都是不可逆的
3.后续处理
当事情达到已解决阶段后,通常需要进行后续处理,不同的以解决状态决定了不同的后续处理
- resolved状态:这是一个正常的以解决状态,后续处理表示为thenable
- rejected状态:这是一个非正常的以解决状态,后续处理表示为catchable
【注】后续处理可能有多个,因此形成作业队列,这些后续处理会按照顺序,当状态到达后依次执行