这是我参与「第四届青训营 」笔记创作活动的第5天
一.观察者模式
一个对象将自身有关的状态在变更够自动通知给观察者,表现上来看发布订阅模式是观察者模式的一个低耦合,降低了发布者和观察者之间的耦合度
promise中的观察者模式
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('result')
},
1000);
})
p1.then(res => console.log(res), err => console.log(err))
调用流程
1.Promise的构造方法接收一个执行函数,在new的时候在构造函数中执行这个函数
2.执行时由于是异步,会被加入到宏/微任务当中去,等待执行
3.then()执行,收集成功或者失败的回调函数,等待执行
4.异步任务开始执行,触发resolve/reject,从成功/失败的队列中取出回调后依次进行执行
then收集依赖 -> 异步触发resolve -> resolve执行依赖
class MyPromise {
_resolveQueue = []
_rejectQueue = []
constructor(executor) {
executor(this._resolve, this._reject) //1.异步,进入宏任务或者微任务等待
}
_resolve = (res) => { //触发任务
let callBack = this._resolveQueue.shift()
callBack(res)
}
_reject = (rej) => {
let callBack = _rejectQueue.shift()
callBack(rej)
}
then = (res, rej) => {
if (res) {
this._resolveQueue.push(res)
}
if (rej) {
this._rejectQueue.push(rej)
}
}
}
let p = new MyPromise((res, rej) => {
console.log(1);
setTimeout(() => {
res('执行成功')
}, 1000)
})
p.then((res) => { //2.将函数加入到队列中, 等待事件此宏任务队列执行完成后由_resolve进行调用
console.log(3);
console.log(res);
})
console.log(2);
二. Promise A+规范
1.Promise本质上是一个状态机,只有三种:Pending(等待态),Fulfilled(执行态),Rejected(拒绝态),且状态变化是单向不可逆的
2.then方法接收两个可选参数,分别对应状态改变时触发的回调。then方法返回一个promise。then 方法可以被同一个 promise 调用多次。
class MyPromise {
PENDING = 'pending'
FULFILLED = 'fulfilled'
REJECTED = 'rejected'
_status = this.PENDING
_resolveQueue = [] //使用队列的原因是因为一个Promise能够被使用多次,尽管状态只由第一次的决定,但是还是需要能执行多次的功能
_rejectQueue = []
constructor(executor) {
executor(this._resolve, this._reject) //1.异步,进入宏任务或者微任务等待
}
_resolve = (res) => {
if (this._status !== this.PENDING) return
this._status = this.FULFILLED
while (this._resolveQueue.length > 0) {
let callBack = this._resolveQueue.shift()
callBack(res)
}
}
_reject = (rej) => {
if (this._status !== this.PENDING) return
this._status = this.REJECTED
while (this._rejectQueue.length > 0) {
let callBack = this._rejectQueue.shift()
callBack(rej)
}
}
then = (res, rej) => {
if (res) {
this._resolveQueue.push(res)
}
if (rej) {
this._rejectQueue.push(rej)
}
}
}
let p = new MyPromise((res, rej) => {
console.log(1);
setTimeout(() => {
res('执行成功')
}, 1000)
})
p.then((res) => { //2.将函数加入到队列中, 等待事件此宏任务队列执行完成后由_resolve进行调用
console.log(3);
console.log(res);
})
console.log(2);
实现链式调用
- 显然.then()需要返回一个Promise,这样才能找到then方法,所以我们会把then方法的返回值包装成Promise。
- .then()的回调需要拿到上一个.then()的返回值
- .then()的回调需要顺序执行。我们要等待当前Promise状态变更后,再执行下一个then收集的回调,这就要求我们对then的返回值分类讨论