在前两篇文章中,分别记录了手写Promise和手写Promise常用方法的过程
JS手写Promise(详细过程)_Eric加油学!的博客-CSDN博客
手写Promise的API(resolve,reject,then,catch,finally,all)_Eric加油学!的博客-CSDN博客
这里将手写的全部代码整理如下:
const resolvePromise = (promise2, x, resolve, reject) => {
// 自己等待自己完成的情况, 直接抛错
if(x === promise2){
return reject(new TypeError('Chaining cycle detected for promise #'))
}
if((typeof x === 'object' && x !== null) || typeof x === 'function'){
let called = false;
try { // 这里防止返回的对象里面,调用then会报错的情况
const then = x.then;
if(typeof then === 'function'){ // 如果then是一个函数,那x就是Promise对象
then.call(x, (y) => {
if(called) return;
called = true;
console.log('test');
resolvePromise(promise2, y, resolve, reject)
},(r) => {
reject(r)
})
} else { // 普通对象,上面有then属性而已
resolve(x)
}
} catch (e) {
if(called) return;
called = true;
console.log('test');
reject(e)
}
}else{
// 不是对象也不是函数,那就是普通值,直接resolve
resolve(x)
}
}
class Promise {
// Promise 等待态(初始状态)
static PENDING = 'pending';
// Promise 失败态
static REJECTED = 'rejected';
// Promise 成功态
static FULFILLED = 'fulfilled';
constructor(executor){
// 初始化 Promise 初始状态
this.status = Promise.PENDING;
// 定义 Promise 成功的值
this.value = undefined
// 定义 Promise 失败的原因
this.reason = undefined;
// 定义存储 then 方法中成功的回调
this.onFulfilledCallbacks = [];
// 定义存储 then 方法中失败的回调
this.onRejectedCallbacks = [];
// 定义 resolve 函数
const resolve = (value) => {
if(value instanceof Promise){
return value.then(resolve,reject);
}
if(this.status === Promise.PENDING){
this.status = Promise.FULFILLED;
this.value = value
this.onFulfilledCallbacks.forEach(fn => fn())
}
}
// 定义 reject 函数
const reject = (reason) => {
if(this.status === Promise.PENDING){
this.status = Promise.REJECTED;
this.reason = reason
this.onRejectedCallbacks.forEach(fn => fn())
}
};
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
static resolve(value){
return new Promise((resolve)=>{
resolve(value)
})
}
static reject(reason){
return new Promise((_, reject)=>{
reject(reason)
})
}
then(onFulfilled,onRejected){
// 遇到实例中 promise.then().then().then()这种写法
// 接收不到参数,我们进行判断,如果传回调了,不变,如果没传回调,给它补上一个函数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
onRejected = typeof onRejected === 'function' ? onRejected : (r) => {throw r}
const promise2 = new Promise((resolve, reject)=>{
if(this.status === Promise.FULFILLED){
setTimeout(()=>{
try {
const x = onFulfilled(this.value)
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e)
}
},0)
}
if(this.status === Promise.REJECTED){
setTimeout(()=>{
try {
const x = onRejected(this.reason)
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e)
}},0)
}
if(this.status === Promise.PENDING){
this.onFulfilledCallbacks.push(() => {
setTimeout(()=>{
try {
const x = onFulfilled(this.value)
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e)
}},0)
})
this.onRejectedCallbacks.push(() => {
setTimeout(()=>{
try {
const x = onRejected(this.reason)
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e)
}
},0)
})
}
})
return promise2
}
catch(catchCallback) {
return this.then(null,catchCallback)
}
finally(finalCallback){
return this.then((value)=>{
return Promise.resolve(finalCallback()).then(()=> value)
},(reason)=>{
return Promise.resolve(finalCallback()).then(() => {throw reason})
})
}
static all(values) {
if (!Array.isArray(values)) {
const type = typeof values;
return new TypeError(`TypeError: ${type} ${values} is not iterable`)
}
return new Promise((resolve, reject) => {
let resultArr = [];
let orderIndex = 0;
const processResultByKey = (value, index) => {
resultArr[index] = value;
if (++orderIndex === values.length) {
resolve(resultArr)
}
}
for (let i = 0; i < values.length; i++) {
let value = values[i];
if (value && typeof value.then === 'function') {
value.then((value) => {
processResultByKey(value, i);
}, reject);
} else {
processResultByKey(value, i);
}
}
});
}
}
module.exports = Promise;
全部的测试代码:
/**
* 实现Promise的测试代码
*/
// const Promise = require('./promise')
// const promise = new Promise((resolve, reject) => {
// setTimeout(()=>{
// resolve('ok')
// },2000)
// });
// const promise2 = promise.then((value) => {
// console.log("promise success:", value);
// return {
// then(onFulfilled,onRejected){
// throw new Error(onFulfilled('ok'))
// }
// }
// }, (reason) => {
// console.log("promise fail:", reason);
// })
// promise2.then((value)=>{
// console.log("promise2 success:", value);
// },(reason)=>{
// console.log("promise2 fail:", reason);
// })
/*
实现Promise API的测试代码
*/
// const Promise = require('./promise')
// Promise的静态方法 resolve
// Promise.resolve(new Promise((resolve, reject) => {
// resolve("ok")
// }))
// .then((value)=>{
// console.log("promise success:", value);
// },(reason)=>{
// console.log("promise fail:", reason);
// })
// Promise的静态方法 reject
// Promise.reject(Promise.resolve('ok'))
// .then((value)=>{
// console.log("promise success:", value);
// },(reason)=>{
// console.log("promise fail:", reason);
// })
// Promise实例上的方法 catch
// const Promise = require('./promise')
// const promise = new Promise((resolve,reject)=>{
// reject('ok')
// })
// promise.then((value)=>{
// console.log("promise success:", value);
// })
// .catch((reason)=>{
// console.log("promise fail:", reason);
// })
// Promise实例上的 finally
// const Promise = require('./promise')
// const promise = new Promise((resolve,reject)=>{
// reject('ok')
// })
// promise
// .finally(()=>{
// console.log("finally");
// return 123
// })
// .then((value)=>{
// console.log("promise success:", value);
// })
// .catch((reason)=>{
// console.log("promise fail:", reason);
// })
// Promise实例上的 all
// const Promise = require('./promise')
// let p1 = new Promise((resolve, reject) => {
// setTimeout(() => {
// resolve('ok1');
// }, 1000);
// })
// let p2 = new Promise((resolve, reject) => {
// setTimeout(() => {
// resolve('ok2');
// }, 1000);
// })
// Promise.all([1,2,3,p1,p2]).then(data => {
// console.log('resolve', data);
// }, err => {
// console.log('reject', err);
// })