完整代码
原生Promise 的用法
1.Promise 是 JavaScript 中用于处理异步操作的重要工具。它代表了一个异步操作的最终完成或失败,并且使异步方法可以像同步方法那样返回值。
- resolve:当异步操作成功时调用的函数,用于将 Promise 的状态改为 fulfilled,并将结果值传递给后续的 .then() 方法。
- reject:当异步操作失败时调用的函数,用于将 Promise 的状态改为 rejected,并将错误原因传递给后续的 .catch() 方法。
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve('操作成功');
} else {
reject('操作失败');
}
}, 1000);
});
2. 使用 .then() 和 .catch()
- then():用于处理 Promise 成功时的回调函数。
- catch():用于处理 Promise 失败时的回调函数。
myPromise
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error(error);
});
3.使用 .finally().
- .finally():无论 Promise 成功还是失败,都会执行的回调函数,通常用于清理工作。
myPromise
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error(error);
})
.finally(() => {
console.log('无论成功还是失败,都会执行这里');
});
4.静态方法
1. Promise.all()
- Promise.all():等待所有 Promise 都成功后,返回一个包含所有结果的数组。如果有一个 Promise 失败,则立即拒绝。
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
Promise.all([promise1, promise2, promise3])
.then((values) => {
console.log(values);
})
.catch((error) => {
console.error(error);
});
2. Promise.race()
- Promise.race():返回第一个完成的 Promise 的结果,无论是成功还是失败。
const promise1 = new Promise((resolve) => setTimeout(resolve, 1000, '1'));
const promise2 = new Promise((resolve) => setTimeout(resolve, 500, '2'));
Promise.race([promise1, promise2])
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error(error);
});
3.Promise.allSettled()
- Promise.allSettled():等待所有 Promise 都完成,无论成功还是失败,返回一个包含每个 Promise 状态和结果的数组。
const promise1 = Promise.resolve(1);
const promise2 = Promise.reject(2);
const promise3 = Promise.resolve(3);
Promise.allSettled([promise1, promise2, promise3])
.then((results) => {
console.log(results);
});
4.Promise.any()
- Promise.any():返回第一个成功完成的 Promise 的结果。如果所有 Promise 都失败,则返回一个包含所有错误的 AggregateError。
const promise1 = Promise.reject(1);
const promise2 = Promise.reject(2);
const promise3 = Promise.resolve(3);
Promise.any([promise1, promise2, promise3])
.then((value) => {
console.log(value);
})
.catch((errors) => {
console.error(errors);
});
手写promise 完整代码
const PROMISE_STATUS_PENDING = "pending";
const PROMISE_STATUS_FULFILLED = "fulfilled";
const PROMISE_STATUS_REJECTED = "rejected";
function execWithCatch(fn, value, resolve, reject) {
try {
const result = fn(value);
resolve(result);
} catch (error) {
reject(error);
}
}
class SmPromise {
constructor(exector) {
this.status = PROMISE_STATUS_PENDING;
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.status == PROMISE_STATUS_PENDING) {
queueMicrotask(() => {
if (this.status != PROMISE_STATUS_PENDING) return;
this.status = PROMISE_STATUS_FULFILLED;
this.value = value;
this.onFulfilledCallbacks.forEach((callback) => {
callback(this.value);
});
});
}
};
const reject = (value) => {
if (this.status == PROMISE_STATUS_PENDING) {
queueMicrotask(() => {
if (this.status != PROMISE_STATUS_PENDING) return;
this.status = PROMISE_STATUS_REJECTED;
this.reason = value;
this.onRejectedCallbacks.forEach((callback) => {
callback(this.reason);
});
});
}
};
try {
exector(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
const defaultOnFulfilled = (value) => value;
const defaultOnRejected = (err) => { throw err;};
onRejected = onRejected ?? defaultOnRejected;
onFulfilled = onFulfilled ?? defaultOnFulfilled;
return new SmPromise((resolve, reject) => {
const handleFulfilled = () => {
execWithCatch(onFulfilled, this.value, resolve, reject);
};
const handleRejected = () => {
execWithCatch(onRejected, this.reason, resolve, reject);
};
if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
handleFulfilled()
}
if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
handleRejected()
}
if (this.status === PROMISE_STATUS_PENDING) {
if (onFulfilled)
this.onFulfilledCallbacks.push(handleFulfilled);
if (onRejected)
this.onRejectedCallbacks.push(handleRejected);
}
});
}
catch(onRejected) {
return this.then(undefined, onRejected);
}
finally(onFinally) {
this.then(
() => {
onFinally();
},
() => {
onFinally();
}
);
}
static resolve(value) {
return new SmPromise((resove) => resove(value));
}
static reject(reason) {
return new SmPromise((resolve, reject) => reject(reason));
}
static all(promises) {
return new SmPromise((resolve, reject) => {
const allPrimiseResult = [];
promises.forEach((promise) => {
promise.then(
(res) => {
allPrimiseResult.push(res);
if (allPrimiseResult.length === promises.length) {
resolve(allPrimiseResult);
}
},
(err) => {
reject(err);
}
);
});
});
}
static allSettled(promises) {
return new SmPromise((resolve, reject) => {
const allPrimiseResult = [];
let completedCount = 0;
promises.forEach((promise, index) => {
SmPromise.resolve(promise)
.then(
(res) => {
allPrimiseResult[index] = {
status: PROMISE_STATUS_FULFILLED,
value: res,
};
},
(err) => {
allPrimiseResult[index] = {
status: PROMISE_STATUS_REJECTED,
err,
};
}
)
.then(() => {
completedCount++;
if (completedCount === promises.length) {
resolve(results);
}
});
});
});
}
static race(promises) {
return new SmPromise((resolve, reject) => {
promises.forEach((promise) => {
SmPromise.resolve(promise).then(resolve, reject);
});
});
}
static any(promises) {
const errors = [];
return new SmPromise((reslove, reject) => {
promise.forEach((promise) => {
promise.then(
(res) => {
reslove(res);
},
(err) => {
errors.push(err);
if (errors.length === promises.length) {
reject(new AggregateError(errors));
}
}
);
});
});
}
}