1.如何使用JS实现Promise 对象?请写出具体代码
Promise其实也不难-CSDN博客
Javascript 手写一个Promise_javascript中手写promise ?-CSDN博客
Promise其实也不难-CSDN博客
题目要求我们使用JavaScript实现一个Promise对象。对此我们可以基于Promise/A+规范的要求进行实现Promise/A+规范是对Promise行为的详细描述确保不同的Promise 实现可以互操作。实现一个符合Promise/A+规范的Promise对象需要处理以下几个核心概念:
1)三种状态: pending (进行中)、fulfilled (已成功)、rejected (已失败)
2)状态不可逆:状态一旦从pending转变为fulfilled 或rejected,就不可再改变。3 ) then方法:用于注册回调函数,处理Promise的成功值或失败原因。
4)异步执行:回调函数需要异步执行。
class MyPromise {
constructor(executor) {
this.state = 'pending'; // 初始状态
this.value = undefined; // 成功值
this.reason = undefined; // 失败原因
this.onFulfilledCallbacks = []; // 成功回调队列
this.onRejectedCallbacks = []; // 失败回调队列
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach((callback) => callback());
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach((callback) => callback());
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
onRejected =
typeof onRejected === 'function'
? onRejected
: (reason) => {
throw reason;
};
const promise2 = new MyPromise((resolve, reject) => {
if (this.state === 'fulfilled') {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
} else if (this.state === 'rejected') {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
} else if (this.state === 'pending') {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
}
});
return promise2;
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === 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;
resolvePromise(promise2, 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('Success');
}, 1000);
});
promise
.then((value) => {
console.log(value); // 输出: 'Success'
return 'Next success';
})
.then((value) => {
console.log(value); // 输出: 'Next success'
})
.catch((error) => {
console.error(error);
});
const promise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('First success');
}, 1000);
});
promise
.then((value) => {
console.log(value); // 输出: 'First success'
return 'Second success';
})
.then((value) => {
console.log(value); // 输出: 'Second success'
return new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('Third success');
}, 1000);
});
})
.then((value) => {
console.log(value); // 输出: 'Third success'
})
.catch((error) => {
console.error(error);
});
const promise = new MyPromise((resolve, reject) => {
setTimeout(() => {
reject('Error occurred');
}, 1000);
});
promise
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error('Caught error:', error); // 输出: 'Caught error: Error occurred'
});
MyPromise.prototype.finally = function (callback) {
return this.then(
(value) => MyPromise.resolve(callback()).then(() => value),
(reason) =>
MyPromise.resolve(callback()).then(() => {
throw reason;
})
);
};
// 使用示例
const promise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('Success');
}, 1000);
});
promise
.then((value) => {
console.log(value); // 输出: 'Success'
})
.finally(() => {
console.log('Finally executed'); // 输出: 'Finally executed'
});
MyPromise.resolve = function (value) {
return new MyPromise((resolve, reject) => {
resolve(value);
});
};
MyPromise.reject = function (reason) {
return new MyPromise((resolve, reject) => {
reject(reason);
});
};
// 使用示例
MyPromise.resolve('Resolved value').then((value) => {
console.log(value); // 输出: 'Resolved value'
});
MyPromise.reject('Rejected reason').catch((reason) => {
console.error(reason); // 输出: 'Rejected reason'
});
2.如何使用JS实现Promise的then方法?请写出具体代码
在 JavaScript 中,Promise
的 .then()
方法是用于处理 Promise
对象解决(resolve)或拒绝(reject)后的结果。Promise
构造函数本身并不直接提供 .then()
方法的实现,但你可以通过创建一个自定义的类来模拟 Promise
的行为,并在这个类中实现 .then()
方法。
然而,通常我们不需要自己实现 Promise
类和它的 .then()
方法,因为 JavaScript 的原生 Promise
已经提供了这些功能。不过,为了教育目的,我可以展示一个简化的 MyPromise
类,它模拟了原生 Promise
的一部分行为,并实现了 .then()
方法。
请注意,这个示例是为了教学目的而简化的,并不包含原生 Promise
的所有功能和错误处理机制。
class MyPromise {
constructor(executor) {
this.state = 'pending'; // 初始状态为pending
this.value = undefined; // 保存resolve的值
this.reason = undefined; // 保存reject的原因
this.onFulfilledCallbacks = []; // 成功回调函数的数组
this.onRejectedCallbacks = []; // 失败回调函数的数组
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn());
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
if (this.state === 'fulfilled') {
onFulfilled(this.value);
} else if (this.state === 'rejected') {
onRejected(this.reason);
} else {
// 如果Promise还在pending状态,将回调函数添加到相应的数组中
this.onFulfilledCallbacks.push(() => onFulfilled(this.value));
this.onRejectedCallbacks.push(() => onRejected(this.reason));
}
// 注意:这里的实现没有返回一个新的Promise,也没有处理链式调用和异步执行的情况
// 这是一个非常简化的版本,仅用于演示目的
// 在实际使用中,你应该返回一个新的Promise来处理这些情况
}
}
// 使用MyPromise的示例(但请注意,这个示例不会按预期工作,因为它缺少了许多关键功能)
// 下面的代码只是为了展示如何调用.then()方法,但它不会正确地处理异步操作
const myPromise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('Success!');
}, 1000);
});
myPromise.then(value => {
console.log(value); // 预期输出: Success!,但实际上这个示例不会工作
});
// 要使上面的代码工作,你需要实现一个能够处理异步回调和链式调用的.then()方法
// 这通常涉及到返回一个新的Promise,并在适当的时机调用resolve或reject
然而,上面的 MyPromise
类并没有正确地实现 .then()
方法,因为它没有处理异步回调和链式调用。在真实的 Promise
实现中,.then()
方法会返回一个新的 Promise
,这个新的 Promise
会根据传入的 onFulfilled
或 onRejected
回调函数的执行结果来解决或拒绝。
为了正确地实现 .then()
方法,你需要更复杂的逻辑,包括:
- 创建一个新的
Promise
。 - 在
onFulfilled
或onRejected
回调函数中,根据执行结果来解决或拒绝这个新的Promise
。 - 确保
onFulfilled
和onRejected
回调在适当的时机(即原始Promise
解决或拒绝后)以异步方式执行。
3.如何使用JS实现Promise的all方法?请写出具体代码
function myPromiseAll(promises) {
return new Promise((resolve, reject) => {
const results = []; // 用于存储每个Promise的解决值
let count = 0; // 已解决的Promise计数器
// 遍历promises数组,为每个Promise添加.then()处理器
promises.forEach((promise, index) => {
promise.then(
value => {
results[index] = value; // 存储解决值
count++; // 增加计数器
// 如果所有Promise都已解决,则调用resolve
if (count === promises.length) {
resolve(results);
}
},
reason => {
// 如果有任何一个Promise被拒绝,则立即调用reject
reject(reason);
}
);
});
});
}
// 使用myPromiseAll的示例
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
myPromiseAll([promise1, promise2, promise3]).then(values => {
console.log(values); // 输出: [1, 2, 3]
});
// 另一个示例,其中一个Promise被拒绝
const promise4 = Promise.resolve(4);
const promise5 = Promise.reject('Error!');
myPromiseAll([promise4, promise5]).catch(error => {
console.log(error); // 输出: Error!
});
4.如何使用JS实现Promise的race方法?请写出具体代码
在 JavaScript 中,Promise.race
方法接受一个可迭代对象(通常是数组)作为输入,该对象包含多个 Promise
对象(或可转换为 Promise
的对象)。它返回一个新的 Promise
,该 Promise
的解决(resolve)或拒绝(reject)状态由第一个解决或拒绝的输入 Promise
决定。如果第一个 Promise
解决,则返回的 Promise
也以相同的值解决;如果第一个 Promise
拒绝,则返回的 Promise
也以相同的拒绝原因被拒绝。
下面是一个简化的 myPromiseRace
函数,它模拟了 Promise.race
的行为:
function myPromiseRace(promises) {
return new Promise((resolve, reject) => {
// 遍历promises数组,为每个Promise添加.then()和.catch()处理器
promises.forEach(promise => {
promise.then(value => {
// 如果当前Promise解决,则立即解决返回的Promise
resolve(value);
// 注意:一旦resolve或reject被调用,Promise的状态就变为final,后续的.then或.catch不会被执行
}).catch(reason => {
// 如果当前Promise拒绝,则立即拒绝返回的Promise
reject(reason);
});
// 为了防止多个Promise同时解决或拒绝时导致多次调用resolve或reject,
// 我们不需要额外的逻辑来阻止这种情况,因为Promise规范保证了resolve和reject只会被调用一次。
});
});
}
// 使用myPromiseRace的示例
const promise1 = new Promise((resolve) => setTimeout(resolve, 500, 'one'));
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'two'));
myPromiseRace([promise1, promise2]).then(value => {
console.log(value); // 不会执行,因为promise2更快地被拒绝了
}).catch(reason => {
console.log(reason); // 输出: two
});
// 另一个示例,其中promise1更快地解决
const promise3 = new Promise((resolve) => setTimeout(resolve, 100, 'three'));
const promise4 = new Promise((resolve) => setTimeout(resolve, 200, 'four'));
myPromiseRace([promise3, promise4]).then(value => {
console.log(value); // 输出: three
}).catch(reason => {
// 不会执行,因为所有Promise都解决了
});
在这个实现中,我们为输入的每个 Promise
对象添加了 .then()
和 .catch()
处理器。由于 Promise
的规范保证了 resolve
和 reject
函数只会被调用一次,并且一旦 Promise
的状态变为 final(即已解决或已拒绝),后续的 .then()
或 .catch()
回调将不会被执行,因此我们不需要额外的逻辑来防止多次调用 resolve
或 reject
。