ES官方参考了大量的异步场景,总结出了一套异步的通用模型,该模型可以覆盖几乎所有的异步场景,甚至是同步场景。
值得注意的是,为了兼容旧系统,ES6 并不打算抛弃掉过去的做法,只是基于该模型推出一个全新的 API,使用该API,会让异步处理更加的简洁优雅。
理解该 API,最重要的,是理解它的异步模型
1. ES6 将某一件可能发生异步操作的事情,分为两个阶段:unsettled 和 settled
**
- unsettled: 未决阶段,表示事情还在进行前期的处理,并没有发生通向结果的那件事
- settled:已决阶段,事情已经有了一个结果,不管这个结果是好是坏,整件事情无法逆转
事情总是从 未决阶段 逐步发展到 已决阶段的。并且,未决阶段拥有控制何时通向已决阶段的能力。
2. ES6将事情划分为三种状态: pending、resolved、rejected
- pending: 挂起,处于未决阶段,则表示这件事情还在挂起(最终的结果还没出来)
- resolved:已处理,已决阶段的一种状态,表示整件事情已经出现结果,并是一个可以按照正常逻辑进行下去的结果
- rejected:已拒绝,已决阶段的一种状态,表示整件事情已经出现结果,并是一个无法按照正常逻辑进行下去的结果,通常用于表示有一个错误
既然未决阶段有权力决定事情的走向,因此,未决阶段可以决定事情最终的状态!
我们将 把事情变为resolved状态的过程叫做:resolve,推向该状态时,可能会传递一些数据
我们将 把事情变为rejected状态的过程叫做:reject,推向该状态时,同样可能会传递一些数据,通常为错误信息
始终记住,无论是阶段,还是状态,是不可逆的!
3. 当事情达到已决阶段后,通常需要进行后续处理,不同的已决状态,决定了不同的后续处理。
- resolved状态:这是一个正常的已决状态,后续处理表示为 thenable
- rejected状态:这是一个非正常的已决状态,后续处理表示为 catchable
后续处理可能有多个,因此会形成作业队列,这些后续处理会按照顺序,当状态到达后依次执行
整件事称之为Promise
案例
理解unsettled 和 settled
function love(girl ,callback){
console.log(`邓哥向女神【${girl}】发出短信`)
setTimeout(() => {
if(Math.random()<0.1){
callback(true)
}else{
callback(false)
}
}, 100);
}
for(let i = 0 ; i < 3 ; i++){
love(i+1,result =>{
if(result){
console.log(`女神【${i+1}】回复啦短信`)
}else{
console.log(`女神【${i+1}】没有回复啦短信`)
}
})
}
红色区域的代码 的意思为 想女神发送短信,并判断女神有没有没回复短信 。这说明还在前期处理阶段并没有发生通向结果的那件事
而蓝色区域代码的意思为 接受结果并输出有没有回复短信,之所以说他是处于settled状态是因为他接收啦结果,函数love的回调函数不就是接收篮筐中函数的结果,箭头函数接收啦函数,那他就是已决阶段
深入unsettle阶段中三种状态 pending、resolved、rejecte
以上代码为例
红色区与蓝色区域看上面的笔记
事情总是从 unsettle阶段 逐步发展到 settled阶段的。并且,未决阶段拥有控制何时通向settled阶段的能力。
然后控制如何通向settled阶段的能力那将要细化为三个阶段
pending: 挂起,处于未决阶段,则表示这件事情还在挂起(最终的结果还没出来),这也是紫色区域为啥会别称作pending阶段,紫色区域处于未决阶段当其结果没之前为pending状态
未决阶段拥有控制何时通向settled的能力,这个能力就是红色区域的蓝色区域与黄色区域,这两个区域会携带数据传入settled阶段中与其对应的状态
始终记住,无论是阶段,还是状态,是不可逆的!
就像是ajax发送数据,你发现数据包数据有误,但是你能让发出去的数据包回来让你改完再发吗,这是不可能的,你只能重新发送一个新的数据包
深入settled阶段
当事情到达已决阶段会根据不同的已决状态决定后续的处理 其对照方式上面有
而resolved状态的后续处理表示为thenable
rejected状态的后续处理表示为catchable如下图
后续处理可能有多个,因此会形成作业队列,这些后续处理会按照顺序,当状态到达后依次执行