setTimeout выполняется перед задачей в очереди микрозадач (очередь заданий)

У меня проблемы с пониманием того, почему мой код ниже регистрирует в следующем порядке: «конец» «тайм-аут выполнен» «обещание»

Я предположил, что «обещание» будет регистрироваться до «истечения времени ожидания», поскольку оно имеет приоритет над задачей очереди обратного вызова (setTimeout). Мое предположение после этого наблюдения заключается в том, что до тех пор, пока не будет вызван .then, обещание не ставит свою задачу в очередь, так как она еще не готова, и, таким образом, позволяет setTimeout выполнять сначала в очереди обратного вызова. Это верно?

const sampleFunction = function(e) {
  setTimeout(() => console.log('timeout done'), 0)
  const data = fetch(`https://jsonplaceholder.typicode.com/comments/1`)
  .then(response => {
    return response.json();
  })
  .then(json => {
    /*doSomething*/
    console.log('promise')
  });
  console.log('end')
}

person 81ackCat    schedule 18.02.2019    source источник
comment
Уже выполненное обещание имеет приоритет над очередью обратного вызова, но ваше обещание не выполняется до тех пор, пока не будет выполнен сетевой запрос.   -  person Patrick Roberts    schedule 19.02.2019


Ответы (1)


Ваш console.log('promise') должен дождаться завершения вашего fetch().then(), что включает в себя сетевую операцию с другим хостом (и, следовательно, ненулевое время).

Ваш setTimeout() должен только подождать, пока sampleFunction() вернется и вы не вернетесь в очередь событий. Итак, поскольку fetch().then() не блокирует и занимает ненулевое количество времени, когда вы впервые возвращаетесь в очередь событий, только setTimeout() готов к работе. Операция по сети все еще будет выполняться в фоновом режиме.

Итак, это не вопрос расстановки приоритетов. Это вопрос порядка выполнения. setTimeout() вставляет свое событие завершения в очередь событий задолго до выполнения fetch() обещания.

Возможно, вы не осознавали, что fetch() не является блокирующим, и его вызов просто инициирует операцию, а затем выполнение вашего кода продолжается после этого?

В консоли вы должны увидеть:

end
timeout done
promise

Пока в вашем fetch() нет ошибок.

person jfriend00    schedule 19.02.2019