Pull to refresh

Comments 5

Ну спасибо! Поглядим подробнее на промисы. Вкупе с данной статьёй может сделать предмет понятным: https://habr.com/ru/post/479062/


Мы видим Promise в списке микрозадач. Когда Promise выполняется и вызывается метод then(), catch() или finally(), функция обратного вызова с методом добавляется в очередь микрозадач. Это означает, что коллбэк с методом не выполняется немедленно, что делает JS код асинхронным.

Т.е. Promise автоматом делает ЛЮБОЙ код асинхронным? Или без асинхронного вызова типа setTimeout() всё равно никакой асинхронности не будет?!


Т.е. функция-исполнитель ниже всегда будет асинхронной:


let promise = new Promise(function(resolve, reject) {
  // функция-исполнитель (executor)
});

Или в неё нужно добавить что-то типа setTimeout():


let promise = new Promise(function(resolve, reject) {
  // эта функция выполнится автоматически, при вызове new Promise

  // через 1 секунду сигнализировать, что задача выполнена с результатом "done"
  setTimeout(() => resolve("done"), 1000);
});

чтобы она была асинхронной?

Здравствуйте. Не смог пройти мимо.
Т.е. Promise автоматом делает ЛЮБОЙ код асинхронным? Или без асинхронного вызова типа setTimeout() всё равно никакой асинхронности не будет?!

1) Извините, что буду отвечать не совсем прямо на ваш вопрос. Но начнем немного с другого. Promise — сквозь призму ваших слов выглядит как функция, которая взяла — что-то сделала магическое — и завершилась, отдав какой то результат. Все, как в классике: есть функция — значит она должна что-то получить на вход и что-то отдать на выход.

Вот тут необходимо немного изменить восприятие того, что такое промис. Промисы — это не сколько прямое получение результата чего-то, сколько запуск некоторой логики во времени. То есть, связавшись с промисом, вы получаете цепочку взаимосвязанных действий, следующих друг за другом, которая в какой-то момент времени закончится с каким-то результатом.

И ваш вопрос не следует воспринимать буквально напрямик: «делает ли промис мой код асинхронным...?» Скорее надо задавать вопрос так. А вот мой код, который я напишу там-то (в executor-e) или тут-то (в коллбеке then() ) или еще где-то (например, в Promise.resolve()) — как он будет выполняться в уже имеющейся системе действий, которые скрыты от ваших глаз под капотом движка JS?

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

2) И тут возникает хороший вопрос. А что же это за система действий, которая выполняется во времени, и которая скрыта от наших глаз? Зная эту систему, и как наш код в неё встраивается, мы легко ответим на множество сейчас неочевидных вопросов. Прямо как система хуков =)

Данная «система действий» довольно хорошо описано в EcmaScript спецификации. Лично вот сам жду, когда же выйдет статья, которая просто и тупо опишет все те шаги, которые описаны в спецификации, только на «понятном русском языке». А то все только описывают теории вокруг да около. Пока ждал, сам прочитал и разобрался. Даже думал серию статей сюда написать…

Немного отвлекся. Ну так вот, возвращаясь к промисам, отвечаю наконец-то прямо на ваш вопрос. Код внутри executor фукнции new Promise( (res, rej)=>{/* тело executor функции */} ) будет выполняться всегда здесь и сейчас, как только интерпретатор дошел до команды new Promise() — то есть всегда синхронно.

И не важно, напишете вы внутри setTimeout или fetch или что-еще — сама executor функция выполнится до финиша, после чего вам вернется на руки промис-объект. Этот промис объект
будет всегда, вот только его состояние определяется тем, был ли синхронно вызван коллбек-res-параметр executor функции внутри executor фукнции, или вызов коллбек-res-параметра отложили когда-то на потом через setTimeout тот же.

Успели синхронно вызвать коллбек-res-параметр — получите промис в состоянии fulfilled после выполнения new Promise(). Перенесли на будущее вызов — получившийся промис будет в состоянии pending.

И если вы думаете, что на этом подковерная цепочка действий внутренней логики промисов завершилась — то это заблуждение. Там потом такие «повороты сюжета» идут — просто… then одним словом.

Если в этой статье для вас не слишком явно описаны первоначальные нюансы использовния промисов — попробуйте эту статью. habr.com/ru/post/478938 — что называется минутка саморекламы. Там ответ на ваш вопрос описан более подробно в подзаголовке «Алгоритм создания promise объекта по спецификации ECMAScript».

Благодарю! Будем разбираться.


А вот мой код, который я напишу там-то (в executor-e) или тут-то (в коллбеке then() ) или еще где-то (например, в Promise.resolve()) — как он будет выполняться в уже имеющейся системе действий, которые скрыты от ваших глаз под капотом движка JS?

Вот насколько же красиво сделали в C# — запустил


await Task.Run( () => { // функция-исполнитель (executor) }


И чётко знаешь, что функция выполняется асинхронно в отдельном потоке без всяких там setTimeout() и прочего.

В какую очередь попадут коллбеки из requestAnimationFrame?
Спасибо! Не знал про нюансы между Promise и Async/Await. Буду учитывать это при разработке.
Sign up to leave a comment.

Articles