wordpress做电影网站,北京工程建设协会网站,东莞虚拟主机,好的设计教程网站文章目录 前言一、前置知识二、实现基本功能二、实现链式调用三、实现Promise.all四、实现Promise.race总结 前言
关于动机#xff0c;无论是在工作还是面试中#xff0c;都会遇到Promise的相关使用和原理#xff0c;手写Promise也有助于学习设计模式以及代码设计。 本文主… 文章目录 前言一、前置知识二、实现基本功能二、实现链式调用三、实现Promise.all四、实现Promise.race总结 前言
关于动机无论是在工作还是面试中都会遇到Promise的相关使用和原理手写Promise也有助于学习设计模式以及代码设计。 本文主要介绍了如何使用自己的代码去实现Promise的一些功能。 以下是本篇文章正文内容
一、前置知识
手写之前需要知道promise有哪些基本特性
1、promise有三种状态pending、fulfilled、rejected。
2、promise的默认状态是pending状态流转有两种pending—fulfilled、pending—rejected。
3、实例化Promise时可以接收一个函数作为参数这个函数有两个参数分别是resolve、reject方法用于改变实例状态。并能够执行下一个then中的回调函数。 4、then方法中接收两个函数作为参数第一个函数相当于执行上一个 promise 中执行 resolve 后对应的回调第二个函数相当于执行上一个 promise 中执行 reject 后对应的回调。
// 1. 实例化 Promise 时
// 可以接收一个函数作为参数这个函数可以接收到 resolve 和 reject 两个实例方法
// 用于更改当前实例的状态并把它们接收到的参数传递给下一个 then 对应的参数中new Promise((resolve, reject) {// resolve 和 reject 可以都执行但都执行的意义不大因为 promise 状态发生更改后就不能在被更改resolve(ok);// reject(err);}).then((value) {console.log(resolve callback , value); // 若执行 resolve则 value ok}, (reason) {console.log(reject callback , reason); // 若执行 reject则 value err});5、then操作后会返回一个新的Promise且支持链式调用。
let promise new Promise((resolve,reject) {resolve(11)
})
const a new Promise((resolve,reject) {reject(ok)
})
promise.then(res {console.log(res)return a
}).then(res console.log(res))6、Promise.all以数组的形式接收多个Promise当所有Promise执行完成且状态都为fulfilled时返回执行成功的结果有一个失败则返回失败的结果。
7、Promise.race以数组的形式接收多个Promise只要有一个Promise先执行成功无论什么状态都返回这个结果给到下一个then中对应的回调。
二、实现基本功能
1、
new 操作resolve、reject方法then方法
// 定义三种状态
const PENDING PENDING;
const FULFILLED FULFILLED;
const REJECTED REJECTED;class Promise {constructor(executor) {// 1、默认状态 - PENDINGthis.status PENDING;// 2、内部维护的变量值this.value undefined;this.reason undefined;try {executor(this.resolve.bind(this), this.reject.bind(this)) // 实例化传进来的函数会立即执行} catch(err) {this.reject(err)}}resolve(value) {if (this.status PENDING) {this.value value;this.status FULFILLED;}}reject(reason) {if (this.status PENDING) {this.reason reason;this.status REJECTED;}}then(onFulfilled, onRejected) {if (onFulfilled this.status FULFILLED) {let res onFulfilled(this.value)this.resolvePromise(res, resolve, reject)}if (onRejected this.status REJECTED) {let res onRejected(this.reason)this.resolvePromise(res, resolve, reject)} }
}通过以下代码自测
new Promise((resolve,reject) {resolve(1)
}).then(res {console.log(res) // 1
})2、考虑异步的情况。 以上代码都是同步的Promise实例化时传入了异步函数如setTimeout在setTimeout中resolve在下一个then的回调函数获取异步函数的状态呢
我们可以使用回调队列缓存起来等待执行
// 定义三种状态
const PENDING PENDING;
const FULFILLED FULFILLED;
const REJECTED REJECTED;class Promise {constructor(executor) {// 1、默认状态 - PENDINGthis.status PENDING;// 2、内部维护的变量值this.value undefined;this.reason undefined;this.onResolveCallBack [];// 缓存 onResolve this.onRejectCallBack [];// 缓存 onReject try {executor(this.resolve.bind(this), this.reject.bind(this)) // 实例化传进来的函数会立即执行} catch(err) {this.reject(err)}}resolve(value) {if (this.status PENDING) {this.value value;this.status FULFILLED;// 遍历调用 onResolveCallBackthis.onResolveCallBack.forEach(fn fn());}}reject(reason) {if (this.status PENDING) {this.reason reason;this.status REJECTED;this.onResolveCallBack.forEach(fn fn());}}then(onFulfilled, onRejected) {if (onFulfilled this.status FULFILLED) {let res onFulfilled(this.value)this.resolvePromise(res, resolve, reject)}if (onRejected this.status REJECTED) {let res onRejected(this.reason)this.resolvePromise(res, resolve, reject)}// 当前 promise 状态为 pending把当前的 onResolve onReject 缓存起来if (this.status PENDING) {this.onResolveCallBack.push(() {onResolve(this.value);}); this.onRejectCallBack.push(() {onReject(this.value);});} }
}用以下代码测试通过 let p new MyPromise((resolve, reject) {setTimeout((){resolve(1);},1000);}).then(value {console.log(then resolve , value);}, reason {console.log(then reject , reason);});
// then resolve 1二、实现链式调用
then(onFulfilled, onRejected) {return new Promise((resolve, reject) { // 支持链式调用if (onFulfilled this.status FULFILLED) {let res onFulfilled(this.value)resolve(res);}if (onRejected this.status REJECTED) {let res onRejected(this.reason)resolve(res);}if (this.status PENDING) {this.onResolvedCallbacks.push(() {let res onFulfilled(this.value)resolve(res);})this.onRejectedCallbacks.push(() {let res onRejected(this.reason)resolve(res);})}}) }测试用例
let promise new Promise((resolve,reject) {resolve(1)
})
promise.then(res {return 2 // 返回普通对象
}).then(res console.log(res)) // 2如果在then中返回的是普通对象上述代码能满足如果返回的是一个Promise则还需要补充
then(onFulfilled, onRejected) {return new Promise((resolve, reject) { // 支持链式调用if (onFulfilled this.status FULFILLED) {let res onFulfilled(this.value)this.resolvePromise(res, resolve, reject)}if (onRejected this.status REJECTED) {let res onRejected(this.reason)this.resolvePromise(res, resolve, reject)}if (this.status PENDING) {this.onResolvedCallbacks.push(() {let res onFulfilled(this.value)this.resolvePromise(res, resolve, reject)})this.onRejectedCallbacks.push(() {let res onRejected(this.reason)this.resolvePromise(res, resolve, reject)})}})}resolvePromise(res, resolve, reject) {if(res instanceof Promise) { // 对then中返回Promise做处理res.then(resolve, reject)} else{// 普通值resolve(res)}}测试用例
let promise new Promise((resolve,reject) {resolve(11)
})
const a new Promise((resolve,reject) {reject(ok)
})
promise.then(res {return a;
}).then(res console.log(res)) // ok三、实现Promise.all
由上述前置知识可知Promise.all是全部成功才返回成功的结果有一个失败就返回失败的结果
Promise.all function(arr) {return new Promise((resolve, reject) {if (!Array.isArray(arr)) {return reject(参数必须为数组);}let successNum 0; // 成功的Promise条数let resultArray [];let totalNum arr.length; // 总Promise数量let isFail false;arr.forEach(item {item.then(res {successNum;resultArray.push(res);if (successNum totalNum) { // 说明是全部成功return resolve(resultArray)}}, err {if (!isFail) reject(err)isFail true;})}); })
}测试用例
function wait500(input) {return new Promise((resolve, reject) {setTimeout(() {resolve(500)}, 500)})
}
function wait1000(input) {return new Promise((resolve, reject) {setTimeout(() {resolve(1000)}, 1000)})
}
// 全部执行完成之后回调
Promise.all([wait1000(), wait500()]).then(result {console.log(all end, result)
}, err {console.log(fafaf, err)
}) // all end [500, 1000]四、实现Promise.race
由上述前置知识可知Promise.race是有一个promise先执行成功无论什么状态都返回这个结果
Promise.race function(arr) {return new Promise((resolve, reject) {if (!Array.isArray(arr)) {return reject(参数必须为数组);}arr.forEach(item {item.then(res {return resolve(res); // 状态不可逆只要其中一个Promise转变了状态后续状态就不会发生改变}, err {reject(err);})}); })}测试用例
function wait500(input) {return new Promise((resolve, reject) {setTimeout(() {resolve(500)}, 500)})
}
function wait1000(input) {return new Promise((resolve, reject) {setTimeout(() {resolve(1000)}, 1000)})
}
Promise.race([wait1000(), wait500()]).then(result {console.log(all end, result)
}, err {console.log(fafaf, err)
}) // 打印出all end 500总结
总的代码
const PENDING PENDING;
const FULFILLED FULFILLED;
const REJECTED REJECTED;class Promise {constructor(executor) {// 1、默认状态 - PENDINGthis.status PENDING;// 2、内部维护的变量值this.value undefined;this.reason undefined;// 存放回调this.onResolvedCallbacks [];this.onRejectedCallbacks [];try {executor(this.resolve.bind(this), this.reject.bind(this))} catch(err) {this.reject(err)}}resolve(value) {if (this.status PENDING) {this.value value;this.status FULFILLED;this.onResolvedCallbacks.forEach(fn fn())}}reject(reason) {if (this.status PENDING) {this.reason reason;this.status REJECTED;this.onRejectedCallbacks.forEach(fn fn())}}then(onFulfilled, onRejected) {return new Promise((resolve, reject) { // 支持链式调用if (onFulfilled this.status FULFILLED) {let res onFulfilled(this.value)this.resolvePromise(res, resolve, reject)}if (onRejected this.status REJECTED) {let res onRejected(this.reason)this.resolvePromise(res, resolve, reject)}if (this.status PENDING) {this.onResolvedCallbacks.push(() {let res onFulfilled(this.value)this.resolvePromise(res, resolve, reject)})this.onRejectedCallbacks.push(() {let res onRejected(this.reason)this.resolvePromise(res, resolve, reject)})}})}resolvePromise(res, resolve, reject) {if(res instanceof Promise) {res.then(resolve, reject)} else{// 普通值resolve(res)}}
}
// 全部成功才返回成功的结果有一个失败就返回失败的结果
Promise.all function(arr) {return new Promise((resolve, reject) {if (!Array.isArray(arr)) {return reject(参数必须为数组);}let successNum 0;let resultArray [];let totalNum arr.length;let isFail false;arr.forEach(item {item.then(res {successNum;resultArray.push(res);if (successNum totalNum) {return resolve(resultArray)}}, err {if (!isFail) reject(err)isFail true;})}); })
}// 某个promise先完成
Promise.race function(arr) {return new Promise((resolve, reject) {if (!Array.isArray(arr)) {return reject(参数必须为数组);}arr.forEach(item {item.then(res {return resolve(res);}, err {reject(err);})}); })}