我有以下代码:
async function get_exam_score() {
const exam_score = Math.random() * 10;
if (exam_score < 5) {
throw("You failed");
}
}
const promise = get_exam_score();
console.log("TRY:", promise);
如果我运行上面的代码,console.log() 显示异步函数承诺已经完成或拒绝状态。 代码与执行
这怎么可能?难道承诺仍然处于挂起状态吗,因为它的微任务及其结果在调用堆栈为空之前不应该能够执行?
我想深入了解 JavaScript 如何管理调用堆栈、微任务队列、事件循环以及与此主题相关的任何内容。这样,在执行 console.log() 时,promise 就处于已确定的状态。
有趣的是,如果我更改函数
get_exam_score
以显式返回 Promise。然后,我确实知道承诺确实处于待处理状态。 代码&执行结果
async function get_exam_score() {
return new Promise((resolve, reject) => {
const exam_score = Math.random() * 10;
if (exam_score < 5) {
reject("You failed");
}
resolve("You passed");
});
}
const promise = get_exam_score();
console.log("TRY:", promise);
为什么这 2 个代码示例会生成不同的输出?
编辑:删除了 try / catch 块,因为它具有误导性。此外,添加了一个代码示例,该示例实际上返回具有待处理状态的承诺。
promise 不应该仍处于挂起状态吗,因为其带有结果的微任务在调用堆栈为空之前不应该能够执行?
该承诺永远不会处于悬而未决的状态。从一开始就已经注定了。但 JS 代码只能通过注册 then
回调(其第一个或第二个参数)或发出
await
来“了解”该状态。排队执行回调的微任务只是“通知”promise 的状态和值。尽管可以同步设置 Promise 的状态,但这种情况是异步发生的。代理(浏览器)无需附加 then
回调即可了解 Promise 的状态,这就是为什么控制台可以同步显示 Promise 的状态,但使用 JS 代码无法同步检查 Promise 的状态。
如果我更改函数
get_exam_score
以显式返回 Promise。然后,我确实知道该承诺确实处于待处理状态。
当您在async
函数中返回 Promise 时,涉及两个 Promise:
return
语句中的 Promise(我们称之为 A)和
async
函数返回的 Promise(我们称之为 B) 。这些是明确的承诺。 Promise B 被“锁定”到 Promise A。隐式地,这是通过在 Promise A 上执行 then
方法调用并以与 Promise A 相同的方式使用回调解析 Promise B 来“在幕后”完成的。由于这个 then
回调是异步执行的,我们可以得出这样的结论:执行 async
语句并以 Promise 作为操作数
always的
return
函数会返回一个挂起的 Promise——无论初始状态是什么给予 return
声明的承诺。