手动实现 Promise
请以官方文档为准
状态
Promise 有三个状态,分别为:
- pending 初始状态
- fulfilled 成功状态
- rejected 失败状态
Promise 的只有在 pending 状态下,才能转更为其他状态,当状态变更后,无法再变更为其他状态。
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
function MyPromise(excutor){
// 初始状态为 pending
this.status = PENDING;
}
立即执行的函数
Promise 接收一个立即执行的函数(执行器:excutor),该函数接收两个回调函数,resolve(成功回调)与 reject(失败回调)。
- resolve 成功回调,将状态改为 fulfilled,并赋予成功的值
- reject 失败回调,将状态改为 rejected,并赋予失败的原因
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
function MyPromise(excutor){
// 初始状态为 pending
this.status = PENDING;
// 成功的值
this.value = undefined;
// 失败的原因
this.reason = undefined;
// then 的回调函数集合,后面会用到
fulfilledCallback = [];
rejectedCallback = [];
const resolve = (value) => {
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
}
}
const reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
}
}
try{
excutor(resolve, reject)
}catch(err){
throw err;
}
}
then 方法
new Promise((...) => {...}).then(res => {}, err => {})
then 用来处理成功或失败状态下的回调,并根据回调的值返回一个新的 Promises
- 接收两个回调函数
- onResolve 成功处理函数
- onReject 失败处理函数
- 返回一个新的 Promise
- 当状态为 fulfilled 时,执行 onResolve,并返回一个新的 Promise,新 Promise 的结果由 onResolve 决定
- 当状态为 rejected 时,执行 onReject,并返回一个新的 Promise,新 Promise 的结果由 onReject 决定
- 当状态为 pending 时,将 onResolve 与 onReject 两个函数保存起来,等待状态变更后再执行对应的函数。
- 由于状态为 pending 时,需要保存两个回调函数,所以需要新建两个数组来保存。
MyPromise.prototype.then = function(onResolve, onReject){
// 如果用户没写 onResolve 或 onReject,就使用默认回调
onResolve = typeof onResolve === 'undefined'?onResolve:value => value;
onReject = typeof onReject === 'undefined'?onReject:reason => {throw reason}
// 返回一个新的 Promise
return new MyPromise((resolve, reject) => {
// 当状态为 fulfilled
if(this.status === FULFILLED){
setTimeout(() => {
try{
// 执行 onResolve
const result = onResolve(this.value);
// onResolve 如果返回一个 Promise,那么该 Promise 将决定 then 返回的 Promise 的结果
if(result instanceof MyPromise){
result.then(resolve, reject)
}else{
resolve(result)
}
}catch(error){
reject(error)
}
})
}
// 当状态为 rejected 时执行,与上面差不多
if(this.status === REJECTED){
try{
// 与上面的唯一区别就是执行的函数与传值不一样
const result = onReject(this.reason);
if(result instanceof MyPromise){
result.then(resolve, reject)
}else{
resolve(result)
}
}catch(error){
reject(error)
}
}
})
}
优化一下上面的方法,顺便实现 pending 状态下的方法。
MyPromise.prototype.then = function(onResolve, onReject){
return new MyPromise((resolve, reject) => {
// 将公用重复部分提取成一个方法
function handleFunc(func, value){
try {
const result = func(value);
// 如果返回一个 Promise
if (result instanceof MyPromise) {
result.then(resolve, reject);
} else {
resolve(result)
}
} catch (err) {
reject(err)
}
}
if (this.status === FULFILLED) {
setTimeout(() => {
handle(onResolve, this.value)
})
}
if (this.status === REJECTED) {
setTimeout(() => {
handle(onReject, this.reason)
})
}
// 状态为 pending,将回调函数保存到前面定义的函数集合中
if (this.status === PENDING) {
// 保存到 fulfilledCallback
this.fulfilledCallback.push(value => {
handle(onResolve, value)
})
// 保存到 rejectedCallback
this.rejectedCallback.push(reason => {
handle(onReject, reason)
})
}
})
}
当状态由 pending 状态变更到其他状态后,then 的回调函数还不会被执行,需要修改执行器 excutor 的两个回调函数,resolve、reject
function MyPromise(excutor){
// 省略一部分代码
const resolve = (value) => {
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
setTimeout(() => {
// 状态变更后执行 then 的回调函数
this.fulfilledCallback.forEach(fn => fn(value))
})
}
}
const reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
setTimeout(() => {
this.rejectedCallback.forEach(fn => fn(reason))
})
}
}
try {
excutor(resolve, reject);
} catch (err) {
throw err;
}
}
reject 方法
MyPromise.reject(reason)
返回一个给定原因的失败的Promise
MyPromise.reject = function(reason){
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
resolve 方法
MyPromise.resolve(value);
返回一个解析过 的 Promise,如果值为另一个 Promise,那么将直接返回这个 Promise。
- 返回一个新的 Promise,注意:该 promise 的状态有可能是成功或失败。
- 如果是普通值,那么将解析为成功状态并返回该值
- 如果值是一个 Promise,那么状态将由这个 Promise 决定
MyPromise.resolve = function(value){
return new MyPromise((resolve, reject) => {
// 如果 value 是一个 Promise,那么结果将由这个 Promise 决定
if(value instanceof MyPromise){
value.then(resolve, reject)
}else{
resolve(value)
}
})
}
all 方法
MyPromise.all([promise1, promise2]).then(([p1, p2]) => {}, reason => {})
等待所有 promise 都成功或有一个失败后,返回一个所有 promise 的成功结果的数组或返回一个失败的原因。
- 接收一个数组,数组的元素可以是一个 promise,也可以是一个普通值
- 返回一个新的 promise
- 只要有一个失败,promise.all 就会完全失败。并返回失败状态的 promise
- 成功状态下,存入多少个 Promise 就返回多少个成功的结果,并且结果的位置与传入 Promise 的位置相同
MyPromise.all = function (promises) {
let results = new Array(promises.length);
let fulfilledCount = 0;
return new MyPromise((resolve, reject) => {
// 如果传入的promise数组为空数组,返回一个带空数组结果的成功的 promise
if (promises.length === 0) {
resolve([])
}
// 处理成功的返回
function fulfilledHandle(value, index) {
fulfilledCount++;
results[index] = value;
if (fulfilledCount === promises.length) {
resolve(results)
}
}
promises.forEach((promise, index) => {
// 如果数组中的元素是一个 promise
if (promise instanceof MyPromise) {
promise.then(res => {
fulfilledHandle(res, index)
}, reason => {
reject(reason)
})
// 不是 promise,直接添加到成功的结果集
} else {
fulfilledHandle(res, index)
}
})
})
}
race 方法
MyPromise.race([promise.resolve(1), promise.reject(2)]).then(res=>{},reason=>{})
该方法返回一个 promise,接收一个数组,一旦数组中的某个 promise 成功或失败,返回的promise就会更具这个状态决定成功或失败。
注意: 只会取第一个成功或失败的 promise 或值,其他的忽略。
MyPromise.race = function (promises) {
return new MyPromise((resolve, reject) => {
promises.forEach(promise => {
if (promise instanceof MyPromise) {
promise.then(resolve, reject)
} else {
resolve(promise)
}
})
})
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!