本文是我在看完尚硅谷Promise教程后整理的手写Promsie,内容可能会稍许有点偏差,仅供参考。
当然,都看到手写Promise了,所以肯定对Promise的基本使用是没问题了,下面就来看看如何手写一份Promise吧。
一、搭建Promise骨架
新建lib文件夹,添加Promise.js文件。
首先采用ES5语法实现,后续会讲解ES6语法实现
// 自定义Promise函数模块: IIFE
(function (window) {
// Promise构造函数
// executor: 执行器函数(同步执行)
function Promise(executor) {
}
// Promise原型对象的then(),指定成功和失败的回调函数,返回一个新的Promise对象
Promise.prototype.then = function (onResolved, onRejected) {
}
// Promise原型对象的catch(),指定失败的回调函数,返回一个新的promise对象
Promise.prototype.catch = function (onRejected) {
}
// Promise函数对象的resolve方法
Promise.resolve = function (value) {
}
// Promise函数对象的reject方法
Promise.reject = function (reason) {
}
// Promise函数对象的all方法
Promise.all = function (promises) {
}
// Promise函数对象的race方法
Promise.race = function (promises) {
}
// 向外暴露promise函数
window.Promise = Promise
})(window)
二、完善构造函数
const PENDING = "pending"
const RESOLVED = "resolved"
const REJECTED = "rejected"
// Promise构造函数
// executor: 执行器函数(同步执行)
function Promise(executor) {
const self = this
self.status = PENDING
self.data = undefined
self.callbacks = []
function resolve(value) {
if (self.status !== PENDING) {
return
}
// 将状态改为resolved
self.status = RESOLVED
// 保存value数据
self.data = value
// 如果有待执行的callback函数,立即异步执行回调函数onResolved
if (self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(callbacksObj => {
callbacksObj.onResolved(value)
})
}, 0);
}
}
function reject(reason) {
if (self.status !== PENDING) {
return
}
// 将状态改为resolved
self.status = REJECTED
// 保存value数据
self.data = reason
// 如果有待执行的callback函数,立即异步执行回调函数onRejected
if (self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(callbacksObj => {
callbacksObj.onRejected(reason)
})
}, 0);
}
}
// 立即同步执行executor
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
三、完善then方法
Promise.prototype.then = function (onResolved, onRejected) {
onResolved = typeof onResolved === 'function' ? onResolved : value => value
onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}
const self = this
return new Promise((resolve, reject) => {
function handle(callback) {
try {
const result = callback(self.data)
if (result instanceof Promise) {
result.then(
value => resolve(value),
reason => reject(reason)
)
// 简洁版
// result.then(resolve, reject)
} else {
resolve(result)
}
} catch (error) {
reject(error)
}
}
if (self.status === PENDING) {
self.callbacks.push({
onResolved (value) {
handle(onResolved)
},
onRejected (reason) {
handle(onRejected)
}
})
} else if (self.status === RESOLVED) {
setTimeout(() => {
handle(onResolved)
});
} else { // self.status = REJECTED
setTimeout(() => {
handle(onRejected)
});
}
})
}
四、完善catch方法
// Promise原型对象的catch(),指定失败的回调函数,返回一个新的promise对象
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
五、完善resolve方法
// Promise函数对象的 resolve 方法
//返回一个新的Promise对象,Promise.resolve()中可以传入Promise
Promise.resolve = function (value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(resolve, reject)
} else {
resolve(value)
}
})
}
六、完善reject方法
// Promise函数对象的 reject 方法
//返回一个新的Promise对象 Promise.reject中不能再传入Promise
Promise.reject = function (reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
七、完善all方法
// Promise函数对象的all方法
Promise.all = function (promises) {
const values = new Array(promises.length)
let successCount = 0
return new Promise((resolve, reject) => {
promises.forEach((p, index) => {
Promise.resolve(p).then(
value => {
successCount++
values[index] = value
if (successCount === promises.length) {
resolve(values)
}
},
// 如果失败
reason => {
reject(reason)
}
)
})
})
}
八、完善race方法
// Promise函数对象的race方法
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
promises.forEach(p => {
Promise.resolve(p).then(
value => {
resolve(value)
}, reason => {
reject(reason)
}
)
})
})
}
总结:
-
es5版本
// 自定义Promise函数模块: IIFE (function (window) { const PENDING = 'pending' const RESOLVED = 'resolved' const REJECTED = 'rejected' // Promise构造函数 // executor: 执行器函数(同步执行) function Promise(executor) { const self = this self.status = PENDING self.data = undefined self.callbacks = [] function resolve(value) { if (self.status !== PENDING) { return } // 将状态改为resolved self.status = RESOLVED // 保存value数据 self.data = value // 如果有待执行的callback函数,立即异步执行回调函数onResolved if (self.callbacks.length > 0) { setTimeout(() => { self.callbacks.forEach(callbacksObj => { callbacksObj.onResolved(value) }) }); } } function reject(reason) { if (self.status !== PENDING) { return } // 将状态改为resolved self.status = REJECTED // 保存value数据 self.data = reason // 如果有待执行的callback函数,立即异步执行回调函数onRejected if (self.callbacks.length > 0) { setTimeout(() => { self.callbacks.forEach(callbacksObj => { callbacksObj.onRejected(reason) }) }); } } // 立即同步执行executor try { executor(resolve, reject) } catch (error) { reject(error) } } // Promise原型对象的then(),指定成功和失败的回调函数,返回一个新的Promise对象 Promise.prototype.then = function (onResolved, onRejected) { onResolved = typeof onResolved === 'function' ? onResolved : value => value onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason} const self = this return new Promise((resolve, reject) => { function handle(callback) { try { const result = callback(self.data) if (result instanceof Promise) { result.then( value => resolve(value), reason => reject(reason) ) // 简洁版 // result.then(resolve, reject) } else { resolve(result) } } catch (error) { reject(error) } } if (self.status === PENDING) { self.callbacks.push({ onResolved (value) { handle(onResolved) }, onRejected (reason) { handle(onRejected) } }) } else if (self.status === RESOLVED) { setTimeout(() => { handle(onResolved) }); } else { // self.status = REJECTED setTimeout(() => { handle(onRejected) }); } }) } // Promise原型对象的catch(),指定失败的回调函数,返回一个新的promise对象 Promise.prototype.catch = function (onRejected) { return this.then(undefined, onRejected) } // Promise函数对象的 resolve 方法 //返回一个新的Promise对象,Promise.resolve()中可以传入Promise Promise.resolve = function (value) { return new Promise((resolve, reject) => { if (value instanceof Promise) { value.then(resolve, reject) } else { resolve(value) } }) } // Promise函数对象的 reject 方法 //返回一个新的Promise对象 Promise.reject中不能再传入Promise Promise.reject = function (reason) { return new Promise((resolve, reject) => { reject(reason) }) } // Promise函数对象的all方法 Promise.all = function (promises) { const values = new Array(promises.length) let successCount = 0 return new Promise((resolve, reject) => { promises.forEach((p, index) => { Promise.resolve(p).then( value => { successCount++ values[index] = value if (successCount === promises.length) { resolve(values) } }, // 如果失败 reason => { reject(reason) } ) }) }) } // Promise函数对象的race方法 Promise.race = function (promises) { return new Promise((resolve, reject) => { promises.forEach(p => { Promise.resolve(p).then( value => { resolve(value) }, reason => { reject(reason) } ) }) }) } // 向外暴露promise函数 window.Promise = Promise })(window)
-
class版本
(function (window) {
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
class Promise {
constructor(executor) {
const self = this
self.status = PENDING
self.data = undefined
self.callbacks = []
function resolve(value) {
if (self.status !== PENDING) {
return
}
// 将状态改为resolved
self.status = RESOLVED
// 保存value数据
self.data = value
// 如果有待执行的callback函数,立即异步执行回调函数onResolved
if (self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(callbacksObj => {
callbacksObj.onResolved(value)
})
});
}
}
function reject(reason) {
if (self.status !== PENDING) {
return
}
// 将状态改为resolved
self.status = REJECTED
// 保存value数据
self.data = reason
// 如果有待执行的callback函数,立即异步执行回调函数onRejected
if (self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(callbacksObj => {
callbacksObj.onRejected(reason)
})
});
}
}
// 立即同步执行executor
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
// Promise原型对象的then(),指定成功和失败的回调函数,返回一个新的Promise对象
then(onResolved, onRejected) {
onResolved = typeof onResolved === 'function' ? onResolved : value => value
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
const self = this
return new Promise((resolve, reject) => {
function handle(callback) {
try {
const result = callback(self.data)
if (result instanceof Promise) {
result.then(
value => resolve(value),
reason => reject(reason)
)
// 简洁版
// result.then(resolve, reject)
} else {
resolve(result)
}
} catch (error) {
reject(error)
}
}
if (self.status === PENDING) {
self.callbacks.push({
onResolved(value) {
handle(onResolved)
},
onRejected(reason) {
handle(onRejected)
}
})
} else if (self.status === RESOLVED) {
setTimeout(() => {
handle(onResolved)
});
} else { // self.status = REJECTED
setTimeout(() => {
handle(onRejected)
});
}
})
}
// Promise原型对象的catch(),指定失败的回调函数,返回一个新的promise对象
catch(onRejected) {
return this.then(undefined, onRejected)
}
// Promise函数对象的 resolve 方法
//返回一个新的Promise对象,Promise.resolve()中可以传入Promise
static resolve = function (value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(resolve, reject)
} else {
resolve(value)
}
})
}
// Promise函数对象的 reject 方法
//返回一个新的Promise对象 Promise.reject中不能再传入Promise
static reject = function (reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
// Promise函数对象的all方法
static all = function (promises) {
const values = new Array(promises.length)
let successCount = 0
return new Promise((resolve, reject) => {
promises.forEach((p, index) => {
Promise.resolve(p).then(
value => {
successCount++
values[index] = value
if (successCount === promises.length) {
resolve(values)
}
},
// 如果失败
reason => {
reject(reason)
}
)
})
})
}
// Promise函数对象的race方法
static race = function (promises) {
return new Promise((resolve, reject) => {
promises.forEach(p => {
Promise.resolve(p).then(
value => {
resolve(value)
}, reason => {
reject(reason)
}
)
})
})
}
}
// 向外暴露promise函数
window.Promise = Promise
})(window)