这是我试图理解的一段 Vanilla TS 代码:
console.log("-------------------------- (LOG 1)");
setTimeout(() => console.log("-----------------------------(LOG 2)"), 1000);
const fetchedData = fetch("https://pokeapi.co/api/v2/pokemon/ditto");
const fnReturningNewPromise = () => {
return new Promise<string>((resolve, reject) => {
if (1 == 1) {
console.log("LOG 3 - new Promise in return Statement");
resolve("fnReturningNewPromise - resolved");
}
reject("fnReturningNewPromise - rejected");
});
};
const customPromise = new Promise<string>((resolve, reject) => {
if (1 === 1) {
console.log("LOG 4 - new Promise");
resolve("Promise resolved");
} else {
reject("REJECTED");
}
});
fetchedData
.then((res) => {
console.log("LOG 5 - fetchedData 1st then - res.json()");
return res.json();
})
.then((data) => console.log("LOG 6 - with fetching"));
Promise.resolve(1).then((res) =>
console.log("LOG 7 - immidielty resolved", res)
);
customPromise
.then((response) => response)
.then((data) => console.log("LOG 8 - without fetching"));
console.log("LOG 9 - sync code");
setTimeout(() => {
console.log("LOG 10 - setTimeout - immidietly resolved");
}, 0);
fnReturningNewPromise().then((res) =>
console.log("LOG 11 - resolving promise returned from fn: ", res)
);
这是控制台的输出:
-------------------------- (LOG 1)
LOG 4 - new Promise
LOG 9 - sync code
LOG 3 - new Promise in return Statement
LOG 7 - immidielty resolved 1
LOG 11 - resolving promise returned from fn: fnReturningNewPromise - resolved
LOG 8 - without fetching
LOG 10 - setTimeout - immidietly resolved
LOG 5 - fetchedData 1st then - res.json()
LOG 6 - with fetching
-----------------------------(LOG 2)
我试图找出这些日志的顺序来自哪里。这是我的问题:
我很困惑-谁能给我解释一下吗?
我试着在console.log中输出结果,但是最后的效果更让我困惑
Promise 执行器函数同步执行。
所以通过代码寻找同步执行的代码,日志是
“------------------------(日志 1)”
custom promise
的执行者的“log 4 - new Promise”
来自内联代码的“日志 9 - 同步代码”
“LOG 3 - new Promise in return Statement”,来自同步调用函数中的 promise 执行器(“in return statement”不是准确描述)。
承诺作业队列中的作业在来自计时器任务队列的任务之前执行
因此,接下来我们将查找放置在 promise 作业队列(即微任务队列)中的作业
承诺作业队列中的作业可以在队列变空之前添加更多作业运行
所以接下来我们通过队列中已经执行过的promise作业获取放置在promise作业队列中的作业:
超时回调作业的优先级低于 Promise 作业队列中的作业
所以现在可以执行来自定时器任务源的超时处理程序,因为承诺作业队列是空的:
“LOG 10 - setTimeout - 立即解决”)
获取日志
提取操作的日志何时出现取决于操作完成需要多长时间,但是
根据实际输出,它们会在不到一秒内出现。
技术说明
运行 promise 处理程序以监视其行为并继续链式 promise 处理的任务在上面称为“Promise 作业”,因为这就是 ECMAScript 标准中的名称。
Promise 作业队列中的作业优先于其他任务,因为它们是 implemented in HTML5 using the microtask queue.
传递给 setTimeout 等 API 的回调在任务队列中排队。任务队列中的函数只会运行,一旦调用堆栈为空并且没有更多的同步代码要执行。
Promise 表现不同。通过使用 .then() 或 async/await,您可以将函数设置为在 promise 解决后执行。这些函数将转到不同的队列(微任务队列),并在当前堆栈完成其同步代码后立即执行。