最近在掘金上刷面试题的时候不可或非的屡次遇到了Promise的问题,因而经过万能的搜索引擎,研究一番以后终于对Promise的源码才有了一个初步的理解,但愿小伙伴能在此获得一点收获javascript
new 一个promise的时候须要传递一个执行器函数,当即执行
执行器函数只接受两个参数 resolve reject
Promise有三个状态 pedding fulfilled rejectedjava
状态改变只能由pendding -> fulfilled 或者 pendding -> rejected
状态一经肯定就没法改变面试
Promise 的 then 能够链式调用(返回一个promise对象)
可接收两个参数(可缺省),一个是成功的回调onFulfilled 一个是失败的回调onRejected数组
若是成功且有返回值,则若是返回值为Promise对象则等待promise执行完成
若是成功则走下一个Promise成功的回调不然就走失败的回调promise
若是返回值是其余类型则直接做为下一个then对应的成功或失败的回调(在成功的回调返回就走下一个then成功的回调,反之亦然)异步
const PENDDING='pendding';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected'
function Promise(fn){
let self = this;
/**初始化状态*/
self.status=PENDDING;
/**保存成功回调函数*/
self.onFulfilledCallBack=[];
/**保存失败的回到数组*/
self.onRejectedCallBack=[];
/**执行成功回调 */
function resolve(value){
if(self.status===PENDDING){
self.status=FULFILLED;
self.value=value;
self.onFulfilledCallBack.forEach(fn=>fn(self.value))
}
}
/**失败回调*/
function reject(reason){
if(self.status===PENDDING){
self.status=REJECTED;
self.reason=reason;
self.onRejectedCallBack.forEach(fn=>fn(self.reason))
}
}
/**当即执行传入的函数,并加一层捕获异常 */
try {
fn(resolve,reject)
} catch (error) {
reject(error)
}
}
Promise.prototype.then=function(onFulfilled,onRejected){
/**确保用户在没有传入回调函数的时候将值日后传*/
onFulfilled = typeof onFulfilled=== "function"?onFulfilled:value=>value;
onRejected = typeof onRejected=== "function"?onRejected:reason=>{throw reason};
let self=this;
let promise2=new Promise(function(resolve,reject){
if(self.status===FULFILLED){
try {
/**由于Promise是属于微任务,因此在这里须要在外层包裹一个setTimeout 保证它处于异步队列(关于这个问题的具体缘由能够百度一下js事件循环机制) */
setTimeout(()=>{
let x = onFulfilled(self.value);
resolvePromise(promise2,x,resolve,reject)
})
} catch (error) {
reject(error)
}
}else if(self.status===REJECTED){
try {
setTimeout(()=>{
let x = onRejected(self.reason);
resolvePromise(promise2,x,resolve,reject)
})
} catch (error) {
reject(error)
}
}else if(self.status===PENDDING){
/** 若是在调用then函数的时候promise状态还处于pendding状态 则将处理函数分别存入对应的成功或失败的处理函数数组中 */
self.onFulfilledCallBack.push(()=>setTimeout(()=>{
try {
let x = onFulfilled(self.value);
resolvePromise(promise2,x,resolve,reject)
} catch (error) {
reject(error)
}
}))
self.onRejectedCallBack.push(()=>setTimeout(()=>{
try {
let x = onRejected(self.reason);
resolvePromise(promise2,x,resolve,reject)
} catch (error) {
reject(error)
}
}))
}
})
return promise2;
}
/**处理在then函数中返回值*/
function resolvePromise(promise2,x,resolve,reject){
/**确保只执行一次*/
let used;
/**若是出现传入的x==promise2 则会出现死循环,为了为了不这种状况应该在这里加一层判断 */
if(x==promise2){
reject(new TypeError('Chaining cycle'));
}else if(x &&typeof x==='function'||typeof x==='object'){
try {
let then = x.then;
/**在这里加上一层判断是为了不用户传入像{then:""}的对象*/
if(typeof then==='function'){
then.call(x,(y)=>{
if(used)return;
used=true;
resolvePromise(promise2, y, resolve, reject);
},e=>{
if(used)return;
used=true;
reject(e)
})
}else{
if(used)return;
used=true;
resolve(x)
}
} catch (error) {
reject(error)
}
}else{
x&&resolve(x)
}
}
module.exports=Promise
复制代码
能够参考这位大佬的文章
小邵教你玩转promise函数