futureData
на самом деле является обещанием получения, поэтому при вызове fetch
в очередь задач ставится сетевая задача.В результате, printHello
обязательно будет выполнено перед сетевой задачей, поскольку они обе задачи.И метод display
будет помещен в очередь микрозадач только тогда, когда обещание сетевой задачи будет выполнено.Микрозадачи по определению выполняются только в конце каждой задачи.Так что display
будет вызываться в конце сетевой задачи, когда printHello
уже был вызван задолго до этого.
Если вы хотите, чтобы display
вызывался до printHello
, futureData
должентолько очереди микрозадач.Давайте немного изменим ваш пример.
function display(data) {
console.log('hi back from fetch');
}
function printHello() {
console.log('hello');
}
let now = Date.now();
function executeFutureDataWithMicrotasksOnly() {
// Execute microtasks continually in 300ms.
return Promise.resolve().then(() => Date.now() - now < 300 && executeFutureDataWithMicrotasksOnly());
}
function blockfor300ms() {
for (let i = 0; i < 300; i++) {
// just delaying logic
}
}
// this sets the printHello function in callback queue { event loop queue }
setTimeout(printHello, 0);
const futureData = executeFutureDataWithMicrotasksOnly();
// after promise is resolved display function gets added into other queue : Microtask queue { job queue}
futureData.then(display);
// event loop gives prefrence to Microtask queue ( untill its complete)
blockfor300ms();
// which runs first
console.log('Me first !')
Как видно из приведенного выше примера, если вы замените fetch
на метод, имеющий только микрозадачи, порядок выполнения изменится, как и ожидалось, как для fetch
, так и дляexecuteFutureDataWithMicrotasksOnly
выполняются за аналогичный промежуток времени.Когда futureData
больше не ставит задачи в очередь, все микрозадачи, включая display
, будут выполнены в конце текущей выполняемой задачи, которая является предыдущей задачей задачи printHello
.