Arhn - архитектура программирования

Что происходит сначала: setTimeout 0 или await Promise.resolve?

Я вижу такое поведение в Node и Chrome:

setTimeout(()=>{ console.log('timeout') }, 0)
Promise.resolve().then(()=>{ console.log('promise') })
console.log('sync')

// output order:
// sync
// promise
// timeout

Мой вопрос в том, является ли это последовательным поведением? То есть, согласно спецификации, всегда ли срабатывает then или await в мемоизированном/уже разрешенном промисе до setTimeout(fn, 0)?

Я хочу использовать это примерно в следующем, возвращая одно, если у меня есть запомненный результат в моем обещании, и другое, если нет:

// somewhere during object initialization
this.resultingPromise = expensiveAsyncFunction()

// in a method called frequently
Promise.race([
    new Promise(resolve => setTimeout(() => resolve('default'), 0)),
    this.resultingPromise
])

  • Я рискну и скажу, что логика подсказывает, что так будет всегда. Я не знаю внутренней работы любого механизма, но если вы установите таймер, создадите разрешенное обещание, а затем выведете его на консоль, я ожидаю увидеть то, что вы покажете. Журнал console.log работает немедленно, затем создается таймер и настраивается на выполнение обратного вызова, и выполнено разрешенное обещание. Затем выполняется обратный вызов таймера, потому что это будет следующий шаг — обратный отсчет таймера достигает нуля. Мне это кажется разумным, и я верю, что JS разумен. 10.01.2019
  • Эта статья Джейка Арчибальда может помочь прояснить это поведение: jakearchibald.com/2015/ задачи-микрозадачи-очереди-и-расписания 10.01.2019
  • на основе stackoverflow.com/a/36877743/5378743 сводного пункта 2 вы не можете полагаться на заказ. 10.01.2019
  • Спасибо @ArnelleBalane, теперь увидел, что вы опубликовали примерно то же самое до того, как kirill.buga сделал это в своем ответе ниже. Я думаю, что мне следует прочитать о микро-/макрозадачах, чтобы понять это. 10.01.2019

Ответы:


1

Promise.resolve запланирует микрозадачу, а setTimeout запланирует макрозадачу. И микрозадачи будут выполняться до запуска следующей макрозадачи.

Дополнительные сведения о цикле событий в целом: https://www.youtube.com/watch?v=8aGhZQkoFbQ

Дополнительные технические сведения о цикле событий: https://www.youtube.com/watch?v=cCOL7MC4Pl0< /а>

10.01.2019
  • Это немного поучительно, посмотрю видео. Нашел этот ответ stackoverflow.com/a/25933985/1555158, предполагающий, что эта концепция микро-/макрозадач может быть в стандарте WHATWG. . Является ли стандарт WHATWG частью es6 и ему подобных? Или я ошибаюсь, парень ссылается на WHATWG только для того, чтобы указать, что в этом стандарте есть task queue 10.01.2019
  • Хорошо. собирается принять этот ответ. Из приведенной выше ссылки @ArnelleBalane (jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/) кажется, что ECMAScript определяет понятие заданий, а не указывает, что на самом деле является микрозадачами и макрозадачами. Таким образом, несмотря на то, что реализации имеют такое последовательное поведение, я не могу найти ничего, указывающего на то, что они должны всегда иметь указанный выше порядок выполнения. 10.01.2019

  • 2

    Итак, у вас есть 2 асинхронных состояния ожидания, но обратите внимание, что одно из них постоянное, а другое меняется (переменное). Тайм-аут задается в переменной XML, в то время как обещание может занять вечность. Если бы я хорошо понял ваш вопрос, когда у вас есть что-то, на что вы полагаетесь, занимает слишком много времени, а что-то слишком короткое, если только к одному из них не применяется константа, такая как тайм-аут, тогда один из них может неожиданно сократиться (!) Будьте готовы для этого и вместо этого используйте монолитную структуру из соображений безопасности кода, а не производительности.

    10.01.2019
  • Извините, я увидел свою ошибку там. Отредактировал вопрос, чтобы функция выполнялась в setTimeout 10.01.2019

  • 3

    Нет никакой гарантии, что одно будет раньше другого. Если вы хотите гарантировать порядок выполнения — используйте промисы.

    10.01.2019

    4

    Насколько я понимаю, Promise имеет более высокий приоритет в стеке вызовов, чем setTimeout, и, конечно, блок синхронного кода будет выполняться первым. В этом случае да, наблюдаемое выше поведение (в порядке блока синхронного кода, promise.resolve и setTimeout 0) должно быть согласованным.

    10.01.2019
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..