此文适合有Promise基础的同学阅读~~~
构造函数写法
/**
* 构造函数
* @param executor
* @constructor
*/
function Promise(executor) {
// Promise实例的初始状态设置为'pending'
this.PromiseState = 'pending'
// Promise实例的初始值设置为null
this.PromiseResult = null
// Promise.then可以注册多个回调,当resolve()在异步代码中执行时,回调函数在这里保存
this.callbacks = []
// Promise自带的resolve函数
function resolve(data) {
// Promise实例的状态一旦由pending改变之后,不可以再变
if (this.PromiseState !== 'pending') return
// 执行resolve时,将Promise实例的状态修改为'fulfilled'
this.PromiseState = 'fulfilled'
// 执行resolve时,将Promise实例的值修改为resolve函数的参数
this.PromiseResult = data
// 当resolve在同步代码中执行时,将then方法中注册的回调函数放入任务队列,避免回调函数同步执行
// 本应是放入微任务队列,这里用setTimeout放入宏任务队列凑合一下
setTimeout(() => {
// 将then方法中注册的成功回调函数挨个执行
this.callbacks.forEach(item => {
item.onResolved(this.PromiseResult)
})
})
}
// Promise自带的reject函数
function reject(data) {
// Promise实例的状态一旦由pending改变之后,不可以再变
if (this.PromiseState !== 'pending') return
// 执行resolve时,将Promise实例的状态修改为'rejected'
this.PromiseState = 'rejected'
// 执行resolve时,将Promise实例的值修改为reject函数的参数
this.PromiseResult = data
setTimeout(() => {
// 将then方法中注册的失败回调函数挨个执行
this.callbacks.forEach(item => {
item.onRejected(this.PromiseResult)
})
})
}
try {
// new Promise时立即执行构造函数参数中的executor函数,注意这里的this
// 如果不将executor参数中函数的this绑定到Promise实例对象的话,resolve和reject执行时函数中的this会指向window
// 构造函数中的this指向实例对象,因此这里bind(this)的作用是让resolve和reject执行时函数中的this指向Promise实例对象
executor(resolve.bind(this), reject.bind(this))
} catch (e) {
// 如果executor函数中抛出错误,相当于执行reject函数,Promise实例对象的状态变为'rejected'
reject.call(this, e)
}
}
/**
* Promise的then方法,返回一个新的Promise对象
* @param onResolved
* @param onRejected
* @returns {Promise}
*/
Promise.prototype.then = function (onResolved, onRejected) {
// then方法可以不传参,默认成功和失败的回调
if (typeof onRejected !== 'function') {
onRejected = err => {
throw err
}
}
if (typeof onResolved !== 'function') {
onResolved = data => data
}
return new Promise((resolve, reject) => {
// 封装回调函数
let callback = (callbackOn) => {
try {
// 判断回调函数的执行结构
let result = callbackOn(this.PromiseResult)
// 如果回调函数的执行结果返回Promise对象,则根据返回的Promise对象的状态修改then方法返回的Promise对象的状态和值
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
// 如果回调函数的执行结果返回值不是Promise对象,则then方法返回一个状态为fulfilled的Promise对象,值为回调函数的返回值
} else {
resolve(result)
}
// 如果回调函数中报错,则then方法返回一个状态为rejected的Promise对象,值为错误信息
} catch (e) {
reject(e)
}
}
// 一旦调用then方法的Promise对象状态变为fulfilled,将成功的回调放入任务队列,等待执行
// 本应是放入微任务队列,这里用setTimeout放入宏任务队列凑合一下
if (this.PromiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved)
})
}
// 一旦调用then方法的Promise对象状态变为rejected,将失败的回调放入任务队列,等待执行
// 本应是放入微任务队列,这里用setTimeout放入宏任务队列凑合一下
if (this.PromiseState === 'rejected') {
setTimeout(() => {
callback(onRejected)
})
}
// 如果执行到then方法时调用then方法的Promise对象的状态还是pending(在Promise对象的executor函数中执行了异步操作),则将回调函数保存起来,
// 等Promise对象的状态改变时再执行(详见构造函数中定义的resolve和reject函数)
if (this.PromiseState === 'pending') {
this.callbacks.push({
onResolved: () => {
callback(onResolved)
},
onRejected: () => {
callback(onRejected)
}
})
}
})
}
/**
* Promise的catch方法,跟then方法中执行失败的回调没有区别
* @param onRejected
* @returns {Promise}
*/
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
/**
* Promise的resolve方法
* @param value
* @returns {Promise}
*/
Promise.resolve = function (value) {
return new Promise((resolve, reject) => {
// 如果参数是一个Promise对象
if (value instanceof Promise) {
// 根据参数Promise对象的状态确定返回的Promise对象的状态和值
value.then(v => {
resolve(v)
}, r => {
reject(r)
})
// 如果参数不是一个Promise对象,则返回一个状态为fulfilled的Promise对象,值为resolve函数的参数
} else {
resolve(value)
}
})
}
/**
* Promise的reject方法,返回一个Promise实例对象,并将其状态改为rejected,值改为reject函数的参数
* @param reason
* @returns {Promise}
*/
Promise.reject = function (reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
/**
* Promise的all方法,返回一个Promise实例对象,状态为fulfilled,值为数组(参数中所有的Promise实例的状态都变为了fulfilled的情况下),
* 状态为rejected,值为参数中最先执行reject函数的Promise实例的值
* @param promises
* @returns {Promise}
*/
Promise.all = function (promises) {
return new Promise((resolve, reject) => {
let count = 0
let arr = []
for (let i = 0; i < promises.length; i++) {
promises[i].then((res) => {
// 一旦数组中的某个Promise的状态变为'fulfilled',计数器加1,直到数组中所有的Promise对象状态都变成'fulfilled',
// 将返回的Promise对象的状态变为’fulfilled', 值变为数组中所有的Promise对象的值构成的数组(按照先后顺序)
count++
arr[i] = res
if (count === promises.length) {
resolve(arr)
}
}, (err) => {
// 一旦数组中的某个Promise的状态变为'rejected',将返回的Promise对象的状态变为'rejected',
// 值变为数组中状态最先变为'rejected'的Promise对象的值
reject(err)
})
}
})
}
/**
* Promise的race方法,传入Promise对象数组,返回一个新的Promise对象
* @param promises
* @returns {Promise}
*/
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(res => {
// 一旦数组中的某个Promise的状态变为'fulfilled',将返回的Promise对象的状态变为’fulfilled',
// 值变为数组中状态最先变为'fulfilled'的Promise对象的值
resolve(res)
}, err => {
// 一旦数组中的某个Promise的状态变为'rejected',将返回的Promise对象的状态变为'rejected',
// 值变为数组中状态最先变为'rejected'的Promise对象的值
reject(err)
})
}
})
}
封装成类
class Promise {
constructor(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
this.callbacks = []
function resolve(data) {
if (this.PromiseState !== 'pending') return
this.PromiseState = 'fulfilled'
this.PromiseResult = data
setTimeout(() => {
this.callbacks.forEach(item => {
item.onResolved(this.PromiseResult)
})
})
}
function reject(data) {
if (this.PromiseState !== 'pending') return
this.PromiseState = 'rejected'
this.PromiseResult = data
setTimeout(() => {
this.callbacks.forEach(item => {
item.onRejected(this.PromiseResult)
})
})
}
try {
executor(resolve.bind(this), reject.bind(this))
} catch (e) {
reject.call(this, e)
}
}
then(onResolved, onRejected) {
if (typeof onRejected !== 'function') {
onRejected = err => {
throw err
}
}
if (typeof onResolved !== 'function') {
onResolved = data => data
}
return new Promise((resolve, reject) => {
let callback = (callbackOn) => {
try {
let result = callbackOn(this.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
}
if (this.PromiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved)
})
}
if (this.PromiseState === 'rejected') {
setTimeout(() => {
callback(onRejected)
})
}
if (this.PromiseState === 'pending') {
this.callbacks.push({
onResolved: () => {
callback(onResolved)
},
onRejected: () => {
callback(onRejected)
}
})
}
})
}
catch(onRejected) {
return this.then(undefined, onRejected)
}
static resolve(value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(value)
}
})
}
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
static all(promises) {
return new Promise((resolve, reject) => {
let count = 0
let arr = []
for (let i = 0; i < promises.length; i++) {
promises[i].then((res) => {
count++
arr[i] = res
if (count === promises.length) {
resolve(arr)
}
}, (err) => {
reject(err)
})
}
})
}
static race(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(res => {
resolve(res)
}, err => {
reject(err)
})
}
})
}
}
不够清楚或者有误的地方欢迎评论区指正~~~