1 Star 0 Fork 0

zhkch/fed-e-task-01-01

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
myPromise.js 5.37 KB
一键复制 编辑 原始数据 按行查看 历史
zhengkuncheng 提交于 2020-06-20 00:57 . 作业提交
// new Promise((resolve, reject) => {
// resolve('1')
// })
// promise 三种状态,从pending变为其他两种状态,一旦改变就不会再变化了
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
// 捕获执行器中的报错
try{
executor(this.resolve, this.reject)
} catch(e) {
this.reject(e)
}
}
status = PENDING;
value = undefined;
reason = undefined;
successCallback = [];
failCallback = [];
// 在executor中被调用 需要用箭头函数绑定当前实例的this
resolve = (value) => {
// 状态从pending只能改变一次
if (this.status !== PENDING) return
this.status = FULFILLED
// 成功的值,作为成功callback的参数
this.value = value
// executor异步时,改变状态后,调用回调函数
// this.successCallback && this.successCallback(value)
while(this.successCallback.length) {
this.successCallback.shift()()
}
}
// 在executor中被调用 需要用箭头函数绑定当前实例的this
reject = (reason) => {
// 状态从pending只能改变一次
if (this.status !== PENDING) return
this.status = REJECTED
// 失败的值,作为失败callback的参数
this.reason = reason
// executor异步时,改变状态后,调用回调函数
// this.failCallback && this.failCallback(reason)
while(this.failCallback.length) {
this.failCallback.shift()()
}
}
then(successCallback, failCallback) {
// 如果没有声明成功失败回调时,默认把成功值跟失败原因继续传递
successCallback = successCallback ? successCallback : value => value;
failCallback = failCallback ? failCallback : reason => {throw reason};
let newPromise = new MyPromise((resolve ,reject) => {
if (this.status === FULFILLED) {
// 用setTimeout异步,才能获取new出来的对象传递给下面的代码处理
setTimeout(() => {
try {
// 捕获回调执行中的报错
let result = successCallback(this.value)
// 根据返回值判断类型再处理
handleReturn(newPromise,result, resolve, reject)
} catch(e) {
reject(e)
}
}, 0)
} else if(this.status === REJECTED) {
// 用setTimeout异步,才能获取new出来的对象传递给下面的代码处理
setTimeout(() => {
try {
// 捕获回调执行中的报错
let result = failCallback(this.reason)
// 根据返回值判断类型再处理
handleReturn(newPromise,result, resolve, reject)
} catch(e) {
reject(e)
}
}, 0)
} else {
// 处理executor异步情况,且注册了多个回调时
this.successCallback.push(() => {
setTimeout(() => {
try {
// 捕获回调执行中的报错
let result = successCallback(this.value)
// 根据返回值判断类型再处理
handleReturn(newPromise,result, resolve, reject)
} catch(e) {
reject(e)
}
}, 0)
});
this.failCallback.push(() => {
// 用setTimeout异步,才能获取new出来的对象传递给下面的代码处理
setTimeout(() => {
try {
// 捕获回调执行中的报错
let result = failCallback(this.reason)
// 根据返回值判断类型再处理
handleReturn(newPromise,result, resolve, reject)
} catch(e) {
reject(e)
}
}, 0)
});
}
});
return newPromise;
}
finally(callback) {
return this.then(value=> {
return MyPromise.resolve(callback()).then(()=>value);
}, reason => {
return MyPromise.resolve(callback()).then(() => {throw reason})
})
}
catch(callback) {
return this.then(undefined, callback)
}
static all(array) {
let result = [];
let index = 0;
return new MyPromise((resolve, reject) => {
function addData (key, value) {
result[key] = value;
index++;
// 当array中有异步操作时,等待完成后再resolve
if (index === array.length) {
resolve(result)
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i];
if (current instanceof MyPromise) {
current.then(value => addData(i, value), reason => reject(reason))
} else {
addData(i, array[i])
}
}
})
}
static resolve(value) {
if (value instanceof MyPromise) {
return value
} else {
return new MyPromise(resolve => resolve(value))
}
}
static race(array) {
return new MyPromise((resolve,reject) => {
for(let item of array) {
if(item instanceof MyPromise) {
item.then(value => resolve(value)).catch(reason => reject(reason))
} else {
resolve(item)
}
}
})
}
}
function handleReturn(newPromise, result, resolve, reject) {
if (newPromise === result) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (result instanceof MyPromise) {
result.then(resolve, reject)
} else {
resolve(result)
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/zhkch/fed-e-task-01-01.git
git@gitee.com:zhkch/fed-e-task-01-01.git
zhkch
fed-e-task-01-01
fed-e-task-01-01
master

搜索帮助

D67c1975 1850385 1daf7b77 1850385