Обещает ли Promise.resolve(1); использовать очередь микрозадач?

Я ищу, включает ли Promise.resolve(1); какую-либо очередь mcirotask или нет? К нему не прикреплен обработчик .then() или .catch(). Только Promise.resolve(1); Пример:

const v = Promise.resolve(1);

Согласно спецификациям ECMA 2024, я прочитал следующие алгоритмы:

27.2.4.7 Promise.resolve (x)

Эта функция возвращает либо новое обещание, разрешенное с помощью переданного аргумент или сам аргумент, если аргумент представляет собой обещание, созданное этим конструктором.

1. Let C be the this value.
2. If C is not an Object, throw a TypeError exception.
3. Return ? PromiseResolve(C, x).

Примечание. Эта функция ожидает, что это значение будет функцией-конструктором. который поддерживает соглашения о параметрах конструктора Promise.

27.2.4.7.1 PromiseResolve ( C, x )

Абстрактная операция PromiseResolve принимает аргументы C ( конструктор) и x (значение языка ECMAScript) и возвращает либо нормальное завершение, содержащее значение языка ECMAScript или бросок завершение. Он возвращает новое обещание, разрешенное с помощью x. Он выполняет следующие шаги при вызове:

1. If IsPromise(x) is true, then
a. Let xConstructor be ? Get(x, "constructor").
b. If SameValue(xConstructor, C) is true, return x.
2. Let promiseCapability be ? NewPromiseCapability(C).
3. Perform ? Call(promiseCapability.[[Resolve]], undefined, « x »).
4. Return promiseCapability.[[Promise]].

27.2.1.3.2 Функции разрешения обещаний

Функция разрешения обещаний — это анонимная встроенная функция, которая имеет Внутренние слоты [[Promise]] и [[AlreadyResolved]].

Когда функция разрешения обещания вызывается с разрешением аргумента, предпринимаются следующие шаги:

1. Let F be the active function object.
2. Assert: F has a [[Promise]] internal slot whose value is an Object.
3. Let promise be F.[[Promise]].
4. Let alreadyResolved be F.[[AlreadyResolved]].
5. If alreadyResolved.[[Value]] is true, return undefined.
6. Set alreadyResolved.[[Value]] to true.
7. If SameValue(resolution, promise) is true, then
a. Let selfResolutionError be a newly created TypeError object.
b. Perform RejectPromise(promise, selfResolutionError).
c. Return undefined.
8. If resolution is not an Object, then
a. Perform FulfillPromise(promise, resolution).
b. Return undefined.
9. Let then be Completion(Get(resolution, "then")).
10. If then is an abrupt completion, then
a. Perform RejectPromise(promise, then.[[Value]]).
b. Return undefined.
11. Let thenAction be then.[[Value]].
12. If IsCallable(thenAction) is false, then
a. Perform FulfillPromise(promise, resolution).
b. Return undefined.
13. Let thenJobCallback be HostMakeJobCallback(thenAction).
14. Let job be NewPromiseResolveThenableJob(promise, resolution, thenJobCallback).
15. Perform HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]]).
16. Return undefined.
The "length" property of a promise resolve function is 1𝔽.

см. шаг 8.а

27.2.1.4 FulfillPromise (обещание, значение)

Абстрактная операция FulfillPromise принимает аргументы Promise ( Promise) и value (значение языка ECMAScript) и возвращает неиспользованное значение. При вызове он выполняет следующие шаги:

1. Assert: The value of promise.[[PromiseState]] is pending.
2. Let reactions be promise.[[PromiseFulfillReactions]].
3. Set promise.[[PromiseResult]] to value.
4. Set promise.[[PromiseFulfillReactions]] to undefined.
5. Set promise.[[PromiseRejectReactions]] to undefined.
6. Set promise.[[PromiseState]] to fulfilled.
7. Perform TriggerPromiseReactions(reactions, value).
8. Return unused.

Прав ли я, говоря, что Promise.resolve(1) не включает в себя никаких микрозадач?

Попробуйте -> Promise.resolve('there').then(r => console.info(r)); console.info('hello') Обратите внимание, как здесь написано hellothere. Само создание промиса не ставится в очередь, но обратные вызовы then выполняются во время опустошения очереди микрозадач перед следующим циклом событий.

Keith 28.08.2024 16:18

Если в приведенном выше примере вы добавите setTimeout(() => console.info('everyone')); в начало, вы увидите, как теперь написано hellothereeveryone, это потому, что вместо этого тайм-аут будет использовать очередь макрозадач, и она имеет более низкий приоритет, чем микрозадача, и обрабатывается во время следующего события. петля.

Keith 28.08.2024 16:21

IOW: Promise.resolve(1); действительно не включает никаких микрозадач, он становится актуальным везде, где у вас есть then обратные вызовы, и именно при обработке очереди микрозадач. Обратите внимание, что, возможно, стоит отметить, что обработка очереди микрозадач на самом деле sync, а не async, даже если кажется, что это async..

Keith 28.08.2024 16:26

@Кейт, кажется, это необычное определение слова «синхронизация», которое ты там используешь.

trincot 28.08.2024 16:39

@trincot Может быть, какое слово вы бы предложили вместо этого? По сути, я просто указываю на то, что очередь не обрабатывается асинхронно, IOW: вы даже можете заблокировать свой браузер, если вы связали обещания в цепочку без каких-либо реальных async операций между ними.

Keith 28.08.2024 16:42

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

trincot 28.08.2024 16:45

@aLearner, похоже, процитировав спецификации, вы ответили на свой вопрос.

trincot 28.08.2024 16:48

Для меня @trincot async — это основной event цикл, микрозадачи выполняются перед следующим циклом событий. Если в спецификациях указано, что обработка очереди microtask классифицируется как async, то пусть будет так. Но лично я не думаю, что это имеет какой-либо смысл.

Keith 28.08.2024 16:52

Хотя для меня это имеет большой смысл.

trincot 28.08.2024 16:56

@trincot const delay = () => {const t = Date.now()+1000; while (Date.now() < t);}; for (let l = 0; l < 10; l ++) { Promise.resolve().then(r => delay()) } Это заблокирует браузер на 10 секунд, если обработка очереди микрозадач была async это должно было заблокировать его только на 1 секунду 10 раз. например. использование setTimeout с l*1000 действительно сделает это. Так что для меня это различие — нечто большее, чем просто приоритет. И независимо от терминологии именно это я и пытался донести.

Keith 28.08.2024 17:18

Конечно, я понимаю вашу точку зрения. Это звучит так запутанно, что у вас другое понятие асинхронности.

trincot 28.08.2024 18:05

@trincot Для меня, если что-то есть async, то это то, что позволяет продолжать цикл событий основного потока, это было в случае, когда я писал код на C и мне приходилось возиться с PeekMessage / Postmessage и т. д. В Javascript есть такие вещи, как fetch / setTimeout и т. д., которые, по моему мнению, являются async, и не блокируют основной цикл событий. И именно поэтому я хотел подчеркнуть, что setTimeout(fn) не будет работать так же, как Promise.resolve().then(). Лучший пример -> shorturl.at/hnj6R

Keith 28.08.2024 18:19

Как я уже написал, я понимаю вашу точку зрения. Вы просто используете другую концепцию «асинхронности» и связываете ее с блокировкой пользовательского интерфейса. Для меня это другое понятие. На ваш взгляд, обратный вызов then может выполняться синхронно. Но в сообществе JavaScript обычно используется слово «асинхронный», обратный вызов then всегда выполняется асинхронно. Посмотрите, например, как слово асинхронный используется в пункте 3.1 спецификации Promises/A+.

trincot 28.08.2024 20:31

Я думаю, что Кит хочет здесь отметить, что .then() является асинхронным, но ВНУТРИ очереди микрозадач САМ синхронизируется. Я ошибаюсь?

a Learner 28.08.2024 20:43

@trincot В этой версии 3.1 вы заметили -> Since the promise implementation is considered platform code, it may itself contain a task-scheduling queue or “trampoline” in which the handlers are called. Техника setTimeout уже давно не используется в браузерах. В некоторых отношениях if — это просто -> const q = [() => console.info('one'),() => console.info('two')]; for (const fn of q) fn();, который запускается перед следующим тиком. Единственное отличие состоит в том, что очередь очищается браузером. Таким образом, вы бы не классифицировали этот фрагмент кода как async?

Keith 28.08.2024 21:09

@trincot, возможно, проблема здесь в том, что вы считаете разумным кодом async и что современные браузеры делают с обещаниями. Насколько я понимаю, код async вообще не использовался в реализации Promise в современных браузерах. В большинстве случаев различие не имеет значения, в конце концов, зачем создавать обещание ни для одного async кода. Но, как я уже говорил, если у вас есть условные обещания, что когда-нибудь вы будете выполнять настоящий async, а иногда и чистый sync код, существует вероятность блокировки браузера или цикла событий узла. Со мной такое уже случалось, и это причина предупреждения.

Keith 28.08.2024 21:17

@Keith Определение «асинхронного» заключается в том, что код выполняется вне обычного потока программы после того, как вызванная функция уже вернулась. Это касается как микрозадач, так и макрозадач.

Bergi 28.08.2024 21:22

Я хочу сказать, что там говорится, что вызовы then асинхронны. Всегда. В нем упоминается микрозадача как реализация, но это не меняет концепции асинхронности. Ключевые слова — «свежий стек». Я понимаю, что вы говорите, но вы постоянно используете слово «асинхронный» не так, как я считаю стандартным (например, в реализации Promises/A+).

trincot 28.08.2024 21:23

@trincot Тогда я возвращаюсь к своему первоначальному вопросу: какую терминологию вы бы использовали для обозначения блокирующего характера опустошения очереди микрозадач? Для меня sync/async кажется таким логичным, что слив очереди событий использует выполнение synchronous. На самом деле я мог бы только что ответить на свой вопрос... Что я должен был сказать: blocking, это помогает.?

Keith 28.08.2024 21:26

Да, вы имеете в виду «блокировку» событий пользовательского интерфейса. Это другая концепция. Но помните, что даже если вы отправляете обратный вызов в очередь с более низким приоритетом, как в случае с setTimeout, вы также блокируете пользовательские события во время выполнения кода JavaScript. Разница в том, что события с более низким приоритетом могут быть обслужены до того, как этот код начнет выполняться. Но как только это произойдет, оно также блокируется.

trincot 28.08.2024 21:31

@Bergi Asynchronous computing is a paradigm where a user doesn't expect a workload to be executed immediately. Instead, the workload is scheduled for execution in the near future without blocking the application's latency-critical path Для меня критический путь приложения, который я бы предположил, - это цикл событий. И оно блокирует его. В любом случае, я думаю, что высказал свою точку зрения, и если терминология в JS соответствует сказанному, то это достаточно справедливо.

Keith 28.08.2024 21:36
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
21
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нет, Promise.resolve(1) не предполагает никаких микрозадач. Как вы правильно заключили, он просто возвращает выполненное обещание: обещание создается, а затем разрешается (в частности: немедленно выполняется) без каких-либо реакций на расписание, прежде чем Promise.resolve вернется.

27.2.1.4 FulfillPromise ( promise, value ) содержит 7. Perform TriggerPromiseReactions(reactions, value). и в 27.2.1.8 TriggerPromiseReactions ( reactions, argument ) шагах находится 1. For each element reaction of reactions, do a. Let job be NewPromiseReactionJob(reaction, argument). b. Perform HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]]).. reactions здесь будет неопределенным, как следует из 27.2.1.4 FulfillPromise ( promise, value ). ТАК каким будет поведение 1. For each element reaction of reactions, do в TriggerPromiseReactions(reactions, value)?
a Learner 29.08.2024 10:42

Нет, это не «неопределенно». Он инициализируется пустым списком в конструкторе, поэтому цикл по этому списку просто ничего не делает.

Bergi 29.08.2024 12:12

Но почему оно попадет в 27.2.3.1 Promise ( executor )? Я использую Promise.resolve(1), как указано в моей первоначальной задаче, поэтому он должен перейти к 27.2.4.7 Promise.resolve ( x ), в соответствии с которым выполняется следующий оператор 4. Set promise.[[PromiseFulfillReactions]] to undefined?

a Learner 29.08.2024 19:47

Он попадает в конструктор обещаний во время NewPromiseCapability(C). Обратите внимание, что promise.[[PromiseFulfillReactions]] = undefined происходит только после «Let reactions be promise.[[PromiseFulfillReactions]]», который представляет собой пустой список, передаваемый TriggerPromiseReactions.

Bergi 29.08.2024 20:13

Другие вопросы по теме