Skip to main content

promise

· 4 min read

简单的promise

时间长了对promise原理慢慢有些生疏,记录实现一个简易的promise加强理解。

// 定义 Promise 的三种状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

class MyPromise {
constructor(executor) {
// 初始状态为 pending
this.status = PENDING;
// 存储成功的值
this.value = undefined;
// 存储失败的原因
this.reason = undefined;
// 存储成功回调
this.onFulfilledCallbacks = [];
// 存储失败回调
this.onRejectedCallbacks = [];

const resolve = (value) => {
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
// 依次执行成功回调
this.onFulfilledCallbacks.forEach((callback) => callback());
}
};

const reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
// 依次执行失败回调
this.onRejectedCallbacks.forEach((callback) => callback());
}
};

try {
// 执行 executor 函数,传入 resolve 和 reject
executor(resolve, reject);
} catch (error) {
// 如果 executor 执行出错,调用 reject
reject(error);
}
}

then(onFulfilled, onRejected) {
// 处理 onFulfilled 不是函数的情况
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
// 处理 onRejected 不是函数的情况
onRejected = typeof onRejected === 'function' ? onRejected : (reason) => { throw reason; };

const newPromise = new MyPromise((resolve, reject) => {
const handleFulfilled = () => {
try {
const x = onFulfilled(this.value);
// 处理 then 方法返回值,根据规范判断是否递归解析
resolvePromise(newPromise, x, resolve, reject);
} catch (error) {
reject(error);
}
};

const handleRejected = () => {
try {
const x = onRejected(this.reason);
// 处理 then 方法返回值,根据规范判断是否递归解析
resolvePromise(newPromise, x, resolve, reject);
} catch (error) {
reject(error);
}
};

if (this.status === FULFILLED) {
// 如果状态已经是 fulfilled,异步执行成功回调
setTimeout(handleFulfilled, 0);
} else if (this.status === REJECTED) {
// 如果状态已经是 rejected,异步执行失败回调
setTimeout(handleRejected, 0);
} else if (this.status === PENDING) {
// 如果状态还是 pending,将回调存储起来
this.onFulfilledCallbacks.push(() => setTimeout(handleFulfilled, 0));
this.onRejectedCallbacks.push(() => setTimeout(handleRejected, 0));
}
});

return newPromise;
}
}

function resolvePromise(promise, x, resolve, reject) {
if (promise === x) {
return reject(new TypeError('Chaining cycle detected for promise'));
}

let called = false;

if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
try {
const then = x.then;
if (typeof then === 'function') {
then.call(
x,
(y) => {
if (called) return;
called = true;
// 递归解析返回的 promise
resolvePromise(promise, y, resolve, reject);
},
(r) => {
if (called) return;
called = true;
reject(r);
}
);
} else {
resolve(x);
}
} catch (error) {
if (called) return;
called = true;
reject(error);
}
} else {
resolve(x);
}
}

// 以下是测试代码
const promise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(100);
}, 1000);
});

promise.then((value) => {
console.log('First then:', value);
return value * 2;
}).then((value) => {
console.log('Second then:', value);
return new MyPromise((resolve) => {
setTimeout(() => {
resolve(value + 50);
}, 1000);
});
}).then((value) => {
console.log('Third then:', value);
});

//导出模块,为测试准备
module.exports = MyPromise;

-安装 ‘promises-aplus-tests’测试工具,并暴露测试适配器

// test.js
const MyPromise = require('../src/somecode/myPromise');

// 包装 MyPromise 以符合测试工具的要求
const adapter = {
resolved: function (value) {
return new MyPromise((resolve) => resolve(value));
},
rejected: function (reason) {
return new MyPromise((_, reject) => reject(reason));
},
deferred: function () {
let resolve, reject;
const promise = new MyPromise((res, rej) => {
resolve = res;
reject = rej;
});
return {
promise,
resolve,
reject
};
}
};

module.exports = adapter;

终端输入 npx '工具名' 文件名 ’

最终结果: 872 passing (16s)