Promise/A+ 规范
要实现一个Promise,首先应该遵守一下 Promise/A+ 规范,Promise/A+涉及较广,这里只介绍核心的部分。
中文翻译规范:juejin.cn/post/684490…
英文翻译规范:promisesaplus.com/
Promise的状态
- promise只有三种状态,请求态(pending)、完成态(fulfilled)、拒绝态(rejected)。
- promise的状态变化是不可逆,只能从pinding=>fulfilled或者pending=>reject
Promise 的then方法
- promise的then方法接受两个参数,一个是onFulfilled,另一个是onRejected。两者必须是函数,如果不是函数会被忽略。
- 如果onFulfilled是函数,当状态变成fulfilled时会触发,并接Resolve传过来的值
- 如果onRejected是函数,当状态变成reject时会触发,并接受Reject传过来的值
- then方法返回的是一个promise
- them方法能多次调用,按照调用顺序执行代码,接受的值是上一次then返回的值
Promise的解析过程
Promise的resolve方法调用时,会根据不同的值进行不同的操作。
- 如果传入的是Promise本生,则抛出一个循环Promise的错误
- 如果传入的是一个新的Promise,则会等待新的Promise状态改变后返回新的值,如果新的Promise的状态不是fulfilled,调用新的promise的then方法,直到状态改变为止
- 如果resolve的是一个thenable对象,当成一个新的promise处理。
- 如果是其他值,则按照正常的resolve处理
Promise的流程图
- 当Promise实例化时接受一个回调函数,回调函数接受两个参数一个是resolve,另一个是reject.
- 当实例化后会执行回调函数,当执行成功或者是我们想要的结果时会触发resolve,然后能在then方法中第一个参数捕捉到
- 当执行错误或者不是我们想要的结果时,触发reject,可以在catch中或then的第二个参数中捕捉到

手写promise
需要实现的内容
1、state 存放当前的状态。
2、value 存放成功状态的值。
3、reason 存放失败状态的值。
4、then 方法,返回值也是一个 Promise。
5、catch 方法。
6、finally 方法,成功和失败都会调用一次。
7、静态方法,如 Promise.all、Promise.resolve。
实现步骤
1、实现一个 promise ,在 setTimeout 中去 resolve。 ok
const PENDING = 'pending'
const FULFILLD = 'fulfilled'
const REJECT = 'reject'
class MyPromise {
constructor(fn) {
this.state = PENDING //初始状态我饿pending
this.value = 'undefined' //初始值为value
this.resolveCallback = [] //用来存储then的回调函数
const resolve = (val) => {
this.val = val
this.state = FULFILLD //状态变为fulfilled;
//执行所以的then方法,then可能有多个
this.resolveCallback.map((callBack) => {
callBack(val)
})
}
const reject = (err) => {
this.state = REJECT //状态变为reject
}
fn(resolve, reject)
}
then(onFulfilled, onRejected) {
if (this.state === PENDING) {
this.resolveCallback.push(onFulfilled) //只能在请求态执行
}
}
}
//实验
new MyPromise((resolve) => {
setTimeout(() => {
resolve('step1')
})
}).then((res) => {
console.log(res)//step1
})
2、实现一个 promise,支持同步 resolve。 ok
- 由于初始化的时候then还没有挂载上去,所以此时resolveCallback是个空的数组,所以要等then挂载上去才能执行resolve
//resolve的修改
const resolve=val=>{
setTimeOut(()=>{
this.val = val;
this.state = FULFILLD //状态变为fulfilled;
//执行所以的then方法,then可能有多个
this.resolveCallback.map((callBack) => {
callBack(val)
})
})
}
3、实现一个 promise,防止 resolve 多次。 ok
- 在promise中如果resolve多次,只会resolve第一次的值,实现该步骤只需要在resolve的时候判断下状态是否pending
const resolve=val=>{
setTimeOut(()=>{
if(this.state===PENDING){
this.val = val;
this.state = FULFILLD //状态变为fulfilled;
//执行所以的then方法,then可能有多个
this.resolveCallback.map((callBack) => {
callBack(val)
})
}
})
}
4、实现一个 promise,可以让 then 方法链式调用。 ok
- 要想实现链式调用,then方法必须返回一个promise,并且then方法接受的是一个then返回的值
then(onFulfilled) {
if (this.state === PENDING) {
return new MyPromise((resolve) => {
this.resolveCallback.push(() => {
const x = onFulfilled(this.val)
resolve(x)
})
})
}
}
//去掉callback的val
this.resolveCallback.map((callBack) => {
callBack()
})
5、实现一个 promise,支持空 then 函数。
- 如果传的是一个then的空函数,上面会报错,所以我们要给onFulfilled设置一个默认值,
then(onFulfilled=val=>val)
6、实现一个 promise,支持 then 传递 thenable 对象。 OK
- 如果x是个对象象或者函数把 x.then 赋值给 then
- 如果取 x.then 的值时抛出错误 e ,则以 e 为据因拒绝 promise
- 如果 then 是函数,将 x 作为函数的作用域 this 调用之。传递两个回调函数作为参数,第一个参数叫做 resolvePromise ,第二个参数叫做 rejectPromise:
- 如果 resolvePromise 以值 y 为参数被调用,则运行 [[Resolve]](promise, y)
- 如果 rejectPromise 以据因 r 为参数被调用,则以据因 r 拒绝 promise
then(onFulfilled = (val) => val, onRejected) {
//允许传一个空的then
if (this.state === PENDING) {
const promise2 = new MyPromise((resolve, reject) => {
this.resolveCallback.push(() => {
const x = onFulfilled(this.val)
promiseSolution(promise2, x, resolve, reject)
})
})
return promise2
}
}
function promiseSolution(promise2, x, resolve, reject) {
if ((typeof x === 'object' || typeof x === 'function') && x != null) {
if (x.then && typeof x.then === 'function') {
x.then((y) => {
//如果y也是一个thenAble对象回调即可
resolve(y)
})
} else {
resolve(x)
}
} else {
resolve(x)
}
}
7、实现一个 promise,支持 then 传递 promise 对象(x)。
- 如果x是请求状态(pending),promise必须保持pending直到xfulfilled或rejected
- 如果x是完成态(fulfilled),用相同的值完成fulfillpromise
- 如果x是拒绝态(rejected),用相同的原因rejectpromise
if (x instanceof MyPromise) {
if (x.state === PENDING) {
x.then((y) => {
//如果y也是一个thenAble对象回调即可
promiseSolution(promise2, y, resolve, reject)
}, reject)
} else {
x.state === FULFILLD && resolve(x.value)
x.state === REJECTED && reject(x.value)
}
}
8、实现一个 promise,支持 resolve 传递 promise 对象。
const resolve = (val) => {
if ((typeof val === 'object' || typeof val=== 'function') && val.then) {
promiseSolution(this, val, resolve, reject)
return
}
setTimeout(() => {
//只允许resolve一次
if (this.state === PENDING) {
this.val = val
this.state = FULFILLD //状态变为fulfilled;
//执行所以的then方法,then可能有多个
this.resolveCallback.map((callBack) => {
callBack()
})
}
})
}
9、实现一个 promise,处理 then 中的循环 promise。 ok
- 所谓的循环promise是指在then中返回promise自身,这样会导致死循环。所以promise遇见该情况会抛出异常
//在promiseSolution中判断是否自身的条件拦截。
if(promise2===x)throw new Error('死循环');
10、实现一个 promise,支持静态方法 Promise.all。 ok -promise.all返回的是一个promise。 -所有的promise的运行成功,会返回一个数组,数组的值是所有promise返回的值 -如果有一个promise出现reject,则会reject该错误
static all(promiseArr) {
return new MyPromise((resolve, reject) => {
let times = 0
let result = []
console.log(promiseArr)
for (let i = 0; i < promiseArr.length; i++) {
promiseArr[i].then(
(res) => {
processResolve(res, resolve)
},
(err) => {
console.log(err)
reject(err)
}
)
}
function processResolve(res, resolve) {
times++
result.push(res)
if (times === promiseArr.length) {
resolve(result)
}
}
})
}
11、实现一个 promise,支持 reject 和 catch。
const reject = (err) => {
//状态变为reject
setTimeout(() => {
if (this.state === PENDING) {
this.state = REJECTED
this.reason = err
this.rejectCallback.map((callBack) => {
callBack()
})
}
})
}
this.rejectCallback.push(() => {
const y = onRejected(this.reason)
promiseSolution(promise2, y, resolve, reject)
})
12、实现一个 promise,支持处理完成态或失败态的 then。
- 上面的代码只能处理状态为pending的promise,向下面这种情况,promise已经变为fulfilled状态,所以不会打印

if (this.state === FULFILLD) {
promise2 = new MyPromise((resolve, reject) => {
const x = onFulfilled(this.val)
promiseSolution(promise2, x, resolve, reject)
})
}
if (this.state === REJECTED) {
promise2 = new MyPromise((resolve, reject) => {
const y = onRejected(this.reason)
promiseSolution(promise2, y, resolve, reject)
})
}
完整代码
const PENDING = 'pending'
const FULFILLD = 'fulfilled'
const REJECTED = 'reject'
class MyPromise {
static all(promiseArr) {
return new MyPromise((resolve, reject) => {
let times = 0
let result = []
console.log(promiseArr)
for (let i = 0; i < promiseArr.length; i++) {
promiseArr[i].then(
(res) => {
processResolve(res, resolve)
},
(err) => {
console.log(err)
reject(err)
}
)
}
function processResolve(res, resolve) {
times++
result.push(res)
if (times === promiseArr.length) {
resolve(result)
}
}
})
}
constructor(fn) {
this.state = PENDING //初始状态pending
this.value = undefined //初始值为value
this.reason = undefined
this.resolveCallback = [] //用来存储then的回调函数;
this.rejectCallback = []
const resolve = (val) => {
if (
(typeof val === 'object' || typeof val === 'function') &&
val.then
) {
promiseSolution(this, val, resolve, reject)
return
}
setTimeout(() => {
//只允许resolve一次
if (this.state === PENDING) {
this.val = val
this.state = FULFILLD //状态变为fulfilled;
//执行所以的then方法,then可能有多个
this.resolveCallback.map((callBack) => {
callBack()
})
}
})
}
const reject = (err) => {
//状态变为reject
setTimeout(() => {
if (this.state === PENDING) {
this.state = REJECTED
this.reason = err
this.rejectCallback.map((callBack) => {
callBack()
})
}
})
}
fn(resolve, reject)
}
then(
onFulfilled = (val) => val,
onRejected = (err) => {
throw new error(err)
}
) {
const promise2 = null
//允许传一个空的then
if (this.state === PENDING) {
promise2 = new MyPromise((resolve, reject) => {
this.resolveCallback.push(() => {
const x = onFulfilled(this.val)
promiseSolution(promise2, x, resolve, reject)
})
this.rejectCallback.push(() => {
const y = onRejected(this.reason)
promiseSolution(promise2, y, resolve, reject)
})
})
}
if (this.state === FULFILLD) {
promise2 = new MyPromise((resolve, reject) => {
const x = onFulfilled(this.val)
promiseSolution(promise2, x, resolve, reject)
})
}
if (this.state === REJECTED) {
promise2 = new MyPromise((resolve, reject) => {
const y = onRejected(this.reason)
promiseSolution(promise2, y, resolve, reject)
})
}
return promise2
}
}
function promiseSolution(promise2, x, resolve, reject) {
if (promise2 === x) throw new Error('处理循环promixe,死循环')
if (x instanceof MyPromise) {
if (x.state === PENDING) {
x.then((y) => {
//如果y也是一个thenAble对象回调即可
promiseSolution(promise2, y, resolve, reject)
}, reject)
} else {
x.state === FULFILLD && resolve(x.value)
x.state === REJECTED && reject(x.reason)
}
}
if (
(typeof x === 'object' || typeof x === 'function') &&
x != null &&
x.then
) {
if (x.then && typeof x.then === 'function') {
x.then((y) => {
//如果y也是一个thenAble对象回调即可
promiseSolution(promise2, y, resolve, reject)
})
} else {
resolve(x)
}
} else {
resolve(x)
}
}