js 手写promise
时间: 2023-10-11 21:10:05 浏览: 117
当你需要手写一个 Promise 的时候,你可以按照以下步骤进行:
1. 创建 Promise 构造函数,并传入一个执行器函数作为参数:
```javascript
function MyPromise(executor) {
// TODO: 实现 Promise 的状态和值的存储
}
```
2. 在构造函数中创建状态和值的存储变量,并初始化为初始状态:
```javascript
function MyPromise(executor) {
this.state = 'pending';
this.value = undefined;
// TODO: 实现其他必要的变量和逻辑
}
```
3. 定义 resolve 和 reject 函数,用于在异步操作完成时改变 Promise 的状态和值,并添加对应的回调函数:
```javascript
function MyPromise(executor) {
this.state = 'pending';
this.value = undefined;
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
// TODO: 触发所有注册的成功回调函数
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.value = reason;
// TODO: 触发所有注册的失败回调函数
}
};
// TODO: 调用执行器函数,并传入 resolve 和 reject 函数
}
```
4. 在构造函数中调用执行器函数,并传入 resolve 和 reject 函数:
```javascript
function MyPromise(executor) {
this.state = 'pending';
this.value = undefined;
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
// TODO: 触发所有注册的成功回调函数
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.value = reason;
// TODO: 触发所有注册的失败回调函数
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
```
5. 添加 then 方法,用于注册成功回调函数和失败回调函数,并返回一个新的 Promise 对象:
```javascript
function MyPromise(executor) {
this.state = 'pending';
this.value = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
// TODO: 触发所有注册的成功回调函数
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.value = reason;
// TODO: 触发所有注册的失败回调函数
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
MyPromise.prototype.then = function(onFulfilled, onRejected) {
// 创建新的 Promise 对象
const newPromise = new MyPromise((resolve, reject) => {
// TODO: 根据当前 Promise 的状态和值执行对应的回调函数,并处理返回值
});
// 返回新的 Promise 对象
return newPromise;
};
```
6. 在成功回调函数和失败回调函数中处理返回值,并根据返回值的类型决定新 Promise 对象的状态和值:
```javascript
function MyPromise(executor) {
this.state = 'pending';
this.value = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
// TODO: 触发所有注册的成功回调函数
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.value = reason;
// TODO: 触发所有注册的失败回调函数
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
MyPromise.prototype.then = function(onFulfilled, onRejected) {
const newPromise = new MyPromise((resolve, reject) => {
if (this.state === 'fulfilled') {
// 如果当前 Promise 已经是 fulfilled 状态,则异步执行成功回调函数
setTimeout(() => {
try {
const result = onFulfilled(this.value);
// 处理返回值,并根据返回值的类型决定新 Promise 对象的状态和值
handlePromiseResult(newPromise, result, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
} else if (this.state === 'rejected') {
// 如果当前 Promise 已经是 rejected 状态,则异步执行失败回调函数
setTimeout(() => {
try {
const result = onRejected(this.value);
// 处理返回值,并根据返回值的类型决定新 Promise 对象的状态和值
handlePromiseResult(newPromise, result, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
} else {
// 如果当前 Promise 还是 pending 状态,则将回调函数添加到对应的队列中,等待执行
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const result = onFulfilled(this.value);
handlePromiseResult(newPromise, result, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const result = onRejected(this.value);
handlePromiseResult(newPromise, result, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
}
});
return newPromise;
};
function handlePromiseResult(promise, result, resolve, reject) {
if (promise === result) {
// 如果返回的是当前 Promise 对象本身,则抛出 TypeError
reject(new TypeError('Chaining cycle detected for promise'));
} else if (result instanceof MyPromise) {
// 如果返回的是一个 Promise 对象,则根据其状态和值决定新 Promise 对象的状态和值
if (result.state === 'fulfilled') {
resolve(result.value);
} else if (result.state === 'rejected') {
reject(result.value);
} else {
// 如果返回的 Promise 对象还是 pending 状态,则等待其状态改变后再决定新 Promise 对象的状态和值
result.then(resolve, reject);
}
} else if (result && (typeof result === 'object' || typeof result === 'function')) {
// 如果返回的是一个对象或函数,则尝试获取 then 方法
let then;
try {
then = result.then;
} catch (error) {
reject(error);
}
if (typeof then === 'function') {
// 如果返回值有 then 方法,则将其视为 Promise-like 对象,并调用 then 方法
const promiseLikeObj = new MyPromise(then.bind(result));
promiseLikeObj.then(resolve, reject);
} else {
// 如果返回值没有 then 方法,则将其视为普通值,并将其作为新 Promise 对象的值
resolve(result);
}
} else {
// 如果返回的是一个普通值,则将其作为新 Promise 对象的值
resolve(result);
}
}
```
以上是一个简单的手写 Promise 的实现,仅供参考。实际上,原生的 Promise 还包含了更多的特性和细节,比如处理异步操作、链式调用、错误处理等等。
阅读全文