Created
June 5, 2019 10:54
-
-
Save SirM2z/130a4e6281e0f602047e934c538490b5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const PENDING = "pending"; | |
const RESOLVED = "resolved"; // fulfilled | |
const REJECTED = "rejected"; //rejected | |
class Promise { | |
// 构造函数接受一个执行器作为参数 | |
constructor(executor) { | |
// promise 状态 | |
this.status = PENDING; | |
this.value = undefined; | |
this.reason = undefined; | |
// 成功回调数组 | |
this.onFulfilledCallbacks = []; | |
// 失败回调数组 | |
this.onRejectedCallbacks = []; | |
const resolve = value => { | |
// 实现异步执行 then 方法中的两个参数 onFulfilled onRejected | |
// 对应第4条要求 | |
const timer = setTimeout(() => { | |
if (this.status === PENDING) { | |
clearTimeout(timer); | |
this.value = value; | |
this.status = RESOLVED; | |
this.onFulfilledCallbacks.forEach(func => { | |
func(this.value); | |
}); | |
} | |
}, 0); | |
}; | |
const reject = reason => { | |
// 实现异步执行 then 方法中的两个参数 onFulfilled onRejected | |
// 对应第4条要求 | |
const timer = setTimeout(() => { | |
if (this.status === PENDING) { | |
clearTimeout(timer); | |
this.reason = reason; | |
this.status = REJECTED; | |
this.onRejectedCallbacks.forEach(func => { | |
func(this.reason); | |
}); | |
} | |
}, 0); | |
}; | |
try { | |
// 执行 执行器,并传入两个方法作为参数 | |
executor(resolve, reject); | |
} catch (error) { | |
reject(error); | |
} | |
} | |
// then 方法接受两个方法作为参数 | |
then(onFulfilled, onRejected) { | |
return new Promise((resolve, reject) => { | |
// onFulfilled 不是 function 时设置默认方法 | |
if (typeof onFulfilled !== "function") { | |
onFulfilled = res => res; | |
} | |
this.onFulfilledCallbacks.push(() => { | |
try { | |
const res = onFulfilled(this.value); | |
if (res instanceof Promise) { | |
res.then(resolve, reject); | |
} else { | |
resolve(res); | |
} | |
} catch (error) { | |
reject(error); | |
} | |
}); | |
// onRejected 不是 function 时设置默认方法 | |
if (typeof onRejected !== "function") { | |
onRejected = err => { | |
throw new Error(err instanceof Error ? err.message : err); | |
}; | |
} | |
this.onRejectedCallbacks.push(() => { | |
try { | |
const res = onRejected(this.reason); | |
if (res instanceof Promise) { | |
res.then(resolve, reject); | |
} else { | |
resolve(res); | |
} | |
} catch (error) { | |
reject(error); | |
} | |
}); | |
}) | |
} | |
catch(onRejected) { | |
return this.then(null, onRejected); | |
} | |
static all(promiseAry = []) { | |
return new Promise((resolve, reject) => { | |
let finishNum = 0; | |
let result = []; | |
const len = promiseAry.length; | |
for (let i = 0; i < len; i++) { | |
promiseAry[i].then(val => { | |
finishNum++; | |
result[i] = val; | |
if (finishNum === len) { | |
resolve(result); | |
} | |
}, reject) | |
} | |
}) | |
} | |
static resolve(arg) { | |
return new Promise(function(resolve){ | |
resolve(arg); | |
}); | |
} | |
static reject(arg) { | |
return new Promise(function(resolve, reject){ | |
reject(arg); | |
}); | |
} | |
} | |
module.exports = Promise; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment