Promise 的简单手写实现,没有太严谨,有问题请指正,会及时修改,更多方法的实现后续补充。
Promise 的手写实现
手写实现代码
参照原生的 Promise 输入输出一步步实现。
/*
* 手写Promise
*/
class MyPromise {
#state = "pending"; // promise状态
#resolveCallBacks = []; // 成功的回调队列
#rejectCallBack = null; // 失败的回调
#value = null; // promise当前值
constructor(fn) {
// 构造函数参数必须是函数
if (!fn || typeof fn !== "function") {
throw new Error("Promise resolver undefined is not a function");
}
this.#state = "pending";
this.#resolveCallBacks = [];
this.#rejectCallBack = null;
const reject = (error) => {
setTimeout(() => {
if (this.#state === "pending") {
this.#state = "rejected";
this.#value = error;
// reject状态时,没有传递异常处理函数报个错误提示
if (typeof this.#rejectCallBack === "function") {
this.#rejectCallBack(error);
} else {
console.error("Uncaught (in promise) " + error);
}
}
});
};
const resolve = (response) => {
// resolve参数为promise对象时递归处理
if (response instanceof MyPromise) {
return response.then(resolve, reject);
}
setTimeout(() => {
if (this.#state === "pending") {
this.#state = "fulfilled";
this.#value = response;
this.#resolveCallBacks.forEach((cb) => cb(response));
}
});
};
try {
fn(resolve, reject);
} catch (error) {
reject(error);
}
}
// 静态resolve方法
static resolve(res) {
if (res instanceof MyPromise) {
return res;
}
return new MyPromise((resolve, reject) => {
resolve(res);
});
}
// 静态reject方法
static reject(err) {
if (err instanceof MyPromise) {
return err;
}
return new MyPromise((resolve, reject) => {
reject(err);
});
}
// 静态all方法
static all(promises) {
if (!Array.isArray(promises)) {
return MyPromise.reject(
new TypeError(
`${promises} is not iterable (cannot read property Symbol(Symbol.iterator)`
)
);
} else {
return new MyPromise((resolve, reject) => {
const len = promises.length;
const results = [];
const resolveResults = (value, i) => {
results[i] = value;
if (i + 1 === len) {
resolve(results);
}
};
for (let i = 0; i < len; i++) {
const cur = promises[i];
// 有then方法的调用then方法后存值,没有的直接存值
if (cur && typeof cur.then === "function") {
cur.then((res) => {
resolveResults(res, i);
}, reject);
} else {
resolveResults(cur, i);
}
}
});
}
}
then(success, error) {
return new MyPromise((resolve, reject) => {
/* 参数不是函数时转换为直接返回最终结果的函数 */
if (typeof success !== "function") {
success = (res) => res;
}
/* 异常处理参数不是函数时转换为直接抛出异常的函数 */
if (typeof error !== "function") {
error = (err) => {
throw err;
};
}
const nextTick = globalThis.setImmediate || setTimeout;
if (this.#state === "pending") {
this.#resolveCallBacks.push((res) => {
nextTick(() => {
try {
resolve(success(res));
} catch (error) {
reject(error);
}
});
});
if (typeof this.#rejectCallBack !== "function") {
this.#rejectCallBack = (err) => {
nextTick(() => {
try {
resolve(error(err));
} catch (error) {
reject(error);
}
});
};
}
}
if (this.#state === "fulfilled") {
nextTick(() => {
try {
resolve(success(this.#value));
} catch (error) {
reject(error);
}
});
}
if (this.#state === "rejected") {
nextTick(() => {
try {
reject(error(this.#value));
} catch (error) {
reject(error);
}
});
}
});
}
catch(error) {
return this.then(null, error);
}
finally(fn) {
return this.then(
(res) => MyPromise.resolve(fn()).then(() => res),
(res) =>
MyPromise.resolve(fn()).then(() => {
throw res;
})
);
}
}
测试用例
resolve 为一个 reject 的 promise:
const myPromise = new MyPromise((resolve, reject) => {
resolve(
new MyPromise((res, rej) => {
setTimeout(() => {
rej("err123");
}, 1000);
})
);
});
myPromise
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err); // opt: err123
});
resolve 为一个 resolve 的 promise:
const myPromise = new MyPromise((resolve, reject) => {
resolve(
new MyPromise((res, rej) => {
setTimeout(() => {
res("res123");
}, 1000);
})
);
});
myPromise
.then((res) => {
console.log(res); // opt: res123
})
.catch((err) => {
console.log(err);
});
resolve 为一个普通值:
const myPromise = new MyPromise((resolve, reject) => {
resolve("res123");
});
myPromise
.then((res) => {
console.log(res); // 1、 opt: res123
return "res234";
})
.then((res) => {
console.log(res); // 2、opt: res234
throw new Error("err");
})
.catch((err) => {
console.log(err); // 3、Error: err....
});
reject:
const myPromise = new MyPromise((resolve, reject) => {
reject("err123");
});
myPromise
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err); // opt: err123
})
.catch((err) => {
// 前面的catch生效后,后面的catch就会被忽略,即只能捕获一次
console.log("err:", err);
});
finally:
const myPromise = new MyPromise((resolve, reject) => {
resolve("res123");
});
myPromise
.then((res) => {
console.log(res); // 1、 opt: res123
return "res234";
})
.catch((err) => console.log("err1", err))
.finally((a) => {
console.log("finally:", a); // 2、opt: finally: undefined
return "finally";
})
.then((res) => {
console.log(res); // 2、opt: res234
throw new Error("err");
})
.catch((err) => {
console.log(err); // 3、Error: err....
});
reject 的 finally:
const myPromise = new MyPromise((resolve, reject) => {
reject("err123");
});
myPromise
.catch((err) => {
console.log("err:", err); // 1、opt: err: err123
})
.finally((a) => {
console.log("finally:", a); // 2、opt: finally: undefined
});
all 方法:
MyPromise.all([1, 2, 3, MyPromise.resolve(4)]); // opt: [1, 2, 3, 4];
MyPromise.all([1, 2, 3, MyPromise.reject(4)]); // reject:4