promise (p1, p2, p3) 在
getStates()
外部和 setTimeout
内部的 setTimeout
函数中的执行方式有何不同?
const p1 = new Promise((res) => setTimeout(() => res(100), 100));
const p2 = new Promise((res) => setTimeout(() => res(200), 200));
const p3 = new Promise((res, rej) => setTimeout(() => rej(300), 100));
async function getStates() {
console.log(await promiseState(p1));
console.log(await promiseState(p2));
console.log(await promiseState(p3));
}
console.log("Immediately after initiation:");
getStates();
setTimeout(() => {
console.log("After waiting for 100ms:");
getStates();
}, 100);
promiseState
函数来自MDN并使用Promise.race
:
function promiseState(promise) {
const pendingState = { status: "pending" };
return Promise.race([promise, pendingState]).then(
(value) =>
value === pendingState ? value : { status: "fulfilled", value },
(reason) => ({ status: "rejected", reason }),
);
}
这都是来自 MDN Promise.race
页面的示例。 我认为所有 Promise 都应该返回pendingState 对象,但在
setTimeout
函数中情况并非如此。
promise(p1, p2, p3) 的执行方式有何不同这是很多人对承诺的一个重要误解。承诺没有被“执行”。 Promise 只是报告正在完成的事情,它并不“做”这件事。这是
观察异步操作结果的标准方法。
在该代码中,异步操作是计时器。当您创建承诺(前三行代码)时,计时器就会启动。在 new Promise
new Promise
会被同步调用。该函数的工作是启动 Promise 将报告的异步工作。因此,这三个承诺所报告的工作都开始一次,就在开始时,而不是稍后当您通过getStates
观察它们时。
启动这些计时器后,您将检查承诺状态两次:立即:这是在任何计时器有机会触发之前,因此所有承诺都显示为待处理。
100ms 后:此时,您的两个 Promise 已得到解决(
p1
p3
p2
尚未解决) 200 毫秒)。因此,您看到的结果是
p1
已履行,
p2
待决,
p3
被拒绝。关键是承诺计时器在您创建承诺时启动,而不是稍后。
promiseState
这样的函数是一种反模式,在尝试理解 Promise 如何工作的过程中用途非常有限。即便如此,它也可能会产生误导——当您看到这些信息时,这些信息可能已经过时了。