写在前面
参考了其他promise文章,这里记录一下自己的理解
promiseA+ 规范
- promise有三种状态
pending、fulfilled、rejected,分别代表等待中,成功,失败,而且状态只能更改一次,new实例后初始化pending then返回一个新的Promise,支持链式操作
正文
知道规范后我们先来简单版本,然后一点点补齐内容
基础版
class myPromise {
constructor(fn) {
this.status = 'PENDING'
this.value = undefined // resolve的值
this.reason = undefined // reject的值
this.onFulfilledCallbacks = [] // 成功态回调函数队列
this.onRejectedCallbacks = [] // 失败态回调函数队列
const resolve = value => {
if (this.status !== 'PENDING') return
this.status = 'FULFILLED'
this.value = value
// 如果 resolve 是同步的话 这个回调是空的
this.onFulfilledCallbacks.forEach(fn => fn())
}
const reject = reason => {
if (this.status !== 'PENDING') return
this.status = 'REJECTED'
this.reason = reason
this.onRejectedCallbacks.forEach(fn => fn())
}
try {
fn(resolve, reject)
} catch (err) {
reject(err)
}
}
then(onFulfilled, onRejected) {
switch (this.status) {
case 'PENDING':
// 因为异步 所以一直处于padding转态
this.onFulfilledCallbacks.push(() => onFulfilled(this.value))
this.onRejectedCallbacks.push(() => onRejected(this.reason))
break;
/**
* 如果 resolve 是同步的话 就会执行下面的
* 当处于异步的时候then已经调用过了 即使
* status的状态改变了 也不会执行
*/
case 'FULFILLED':
onFulfilled(this.value)
break;
case 'REJECTED':
onRejected(this.reason)
break;
}
}
}
new MyPromise((resolve, reject) => {
console.log(111)
resolve(1)
// setTimeout(() => resolve(1), 1000)
console.log(222)
}).then(res => {
console.log(res, 'res')
}, rej => {
console.log(rej, 'rej')
})
then的链式调用
then(onFulfilled, onRejected) {
return new myPromise((resolve, reject) => {
let x = null
switch (this.status) {
case 'PENDING':
// 因为异步 所以一直处于padding转态
this.onFulfilledCallbacks.push(() => {
x = onFulfilled(this.value)
resolve(x)
})
this.onRejectedCallbacks.push(() => {
x=onRejected(this.reason)
reject(x)
})
break;
/**
* 如果 resolve 是同步的话 就会执行下面的
* 当处于异步的时候then已经调用了 即使
* status的状态改变了 也不会执行
*/
case 'FULFILLED':
x = onFulfilled(this.value)
resolve(x)
break;
case 'REJECTED':
x = onRejected(this.reason)
reject(x)
break;
}
})
}
new myPromise((resolve, reject) => {
console.log(333)
// resolve(1)
setTimeout(() => resolve(1), 1000)
console.log(222)
}).then(res => {
console.log(res)
return 6
}).then(res => {
console.log(res, 'res')
})
如果说then里面返回一个promise怎么办,这时我们需要封装一下
then(onFulfilled, onRejected) {
let newPromise = new myPromise((resolve, reject) => {
let x = null
switch (this.status) {
case 'PENDING':
// 因为异步 所以一直处于padding转态
this.onFulfilledCallbacks.push(() => {
x = onFulfilled(this.value)
this.resolvePromise(newPromise, x, resolve, reject)
})
this.onRejectedCallbacks.push(() => {
x = onRejected(this.reason)
this.resolvePromise(newPromise, x, resolve, reject)
})
break;
/**
* 如果 resolve 是同步的话 就会执行下面的
* 当处于异步的时候then已经调用了 即使
* status的状态改变了 也不会执行
*/
case 'FULFILLED':
x = onFulfilled(this.value)
this.resolvePromise(newPromise, x, resolve, reject)
break;
case 'REJECTED':
x = onRejected(this.reason)
this.resolvePromise(newPromise, x, resolve, reject)
break;
}
})
return newPromise
}
// 如果返回promise做相应处理 否则直接return 值
resolvePromise(promise, x, resolve, reject) {
if (promise === x) return reject(new TypeError('promise是同一个'))
// 判断 x 是不是promise
if (typeof x === 'object' && x != null || typeof x === 'function') {
try {
if (typeof x.then === 'function') {
x.then(res => {
this.resolvePromise(promise, res, resolve, reject)
}, err => {
reject(err)
})
return
}
resolve(x)
} catch (err) {
reject(err)
}
} else {
// 如果不是直接调用resolve
resolve(x)
}
}
new myPromise((resolve, reject) => {
console.log(333)
// resolve(1)
setTimeout(() => resolve(1), 1000)
console.log(222)
}).then(res => {
return new myPromise((resolve, reject) => {
console.log(2, res)
resolve({
name: "第2个传递的值"
})
})
})
.then(res => {
return new myPromise((resolve, reject) => {
console.log(3, res)
resolve(new myPromise((resolve, reject) => {
console.log(3, res)
resolve({
name: "第3个传递的值"
})
}))
})
})
.then(res => {
console.log(res, '555')
})
all
all(lists) {
let resArr = [] //存储处理结果的数组
let index = 0
return new myPromise((resolve, reject) => {
for (let i = 0; i < lists.length; i++) {
lists[i].then(res => {
resArr[i] = res
index++
if (index === lists.length) {
resolve(resArr)
}
}).catch(err => {
reject(err)
return
})
}
})
}
catch
catch(onReJected) {
return this.then(undefined, onReJected)
}
完整代码
class myPromise {
constructor(fn) {
this.status = 'PENDING'
this.value = undefined // resolve的值
this.reason = undefined // reject的值
this.onFulfilledCallbacks = [] // 成功态回调函数队列
this.onRejectedCallbacks = [] // 失败态回调函数队列
const resolve = value => {
if (this.status !== 'PENDING') return
this.status = 'FULFILLED'
this.value = value
// 如果 resolve 是同步的话 这个回调是空的
this.onFulfilledCallbacks.forEach(fn => fn())
}
const reject = reason => {
if (this.status !== 'PENDING') return
this.status = 'REJECTED'
this.reason = reason
this.onRejectedCallbacks.forEach(fn => fn())
}
try {
fn(resolve, reject)
} catch (err) {
reject(err)
}
}
then(onFulfilled, onRejected) {
let newPromise = new myPromise((resolve, reject) => {
let x = null
switch (this.status) {
case 'PENDING':
// 因为异步 所以一直处于padding转态
this.onFulfilledCallbacks.push(() => {
x = onFulfilled(this.value)
this.resolvePromise(newPromise, x, resolve, reject)
})
this.onRejectedCallbacks.push(() => {
x = onRejected(this.reason)
this.resolvePromise(newPromise, x, resolve, reject)
})
break;
/**
* 如果 resolve 是同步的话 就会执行下面的
* 当处于异步的时候then已经调用了 即使
* status的状态改变了 也不会执行
*/
case 'FULFILLED':
x = onFulfilled(this.value)
this.resolvePromise(newPromise, x, resolve, reject)
break;
case 'REJECTED':
x = onRejected(this.reason)
this.resolvePromise(newPromise, x, resolve, reject)
break;
}
})
return newPromise
}
// 如果返回promise做相应处理 否则直接return 值
resolvePromise(promise, x, resolve, reject) {
if (promise === x) return reject(new TypeError('promise是同一个'))
// 判断 x 是不是promise
if (typeof x === 'object' && x != null || typeof x === 'function') {
try {
if (typeof x.then === 'function') {
x.then(res => {
this.resolvePromise(promise, res, resolve, reject)
}, err => {
reject(err)
})
return
}
resolve(x)
} catch (err) {
reject(err)
}
} else {
// 如果不是直接调用resolve
resolve(x)
}
}
catch(onReJected) {
return this.then(undefined, onReJected)
}
all(lists) {
let resArr = [] //存储处理结果的数组
let index = 0
return new myPromise((resolve, reject) => {
for (let i = 0; i < lists.length; i++) {
lists[i].then(res => {
resArr[i] = res
index++
if (index === lists.length) {
resolve(resArr)
}
}).catch(err => {
reject(err)
return
})
}
})
}
}
new myPromise((resolve, reject) => {
console.log(333)
// resolve(1)
setTimeout(() => resolve(1), 1000)
console.log(222)
}).then(res => {
return new myPromise((resolve, reject) => {
console.log(2, res)
resolve({
name: "第2个传递的值"
})
})
}).then(res => {
return new myPromise((resolve, reject) => {
console.log(3, res)
resolve(new myPromise((resolve, reject) => {
console.log(3, res)
resolve({
name: "第3个传递的值"
})
}))
})
}).then(res => {
console.log(res, '555')
}).catch(err => {
console.log(err, 'err')
})