Skip to content

Latest commit

 

History

History
207 lines (154 loc) · 34.1 KB

ANSWERS-RU.md

File metadata and controls

207 lines (154 loc) · 34.1 KB
  • Question 1: start, 1, end
  1. Сначала выполняется console.log('start'), что выводит "start".
  2. Далее создаётся промис promise1. В конструкторе промиса немедленно выполняется console.log(1), выводя "1".
  3. Поскольку в конструкторе промиса нет ни resolve(), ни reject(), промис остаётся в состоянии "pending" (ожидание), и не вызываются ни .then, ни .catch, если они есть.
  4. Затем выполняется console.log('end'), выводя "end".
  • Question 2: start , 1 , end и 2
  1. Выполнение начинается с console.log('start'), что выводит "start".
  2. При создании промиса promise1, сначала выполняется console.log(1), выводя "1".
  3. Затем вызывается resolve(2), что изменяет состояние промиса на "resolved" (выполнено) с результатом 2.
  4. После создания промиса, следует метод .then(), который должен выполниться после успешного завершения промиса. Однако, поскольку промисы в JavaScript исполняются асинхронно, выполнение .then() откладывается до следующего цикла событий.
  5. Следующей выполняется строка console.log('end'), что выводит "end".
  6. После завершения текущего цикла событий, начинает выполняться обработчик промиса в .then(), который выводит результат 2.
  • Question 3: start , 1 , 3 , end и 2
  1. console.log('start'); – Сначала выводится 'start'. Это синхронный вызов, поэтому он выполняется первым.
  2. const promise1 = new Promise((resolve, reject) => { console.log(1) resolve(2) }) – Здесь создается новый промис. Во время его создания выполняется функция, переданная в конструктор (executor function). Она также синхронная, поэтому сразу выводится 1. После этого вызывается resolve(2), но обработчик .then() для этого промиса выполнится только после того, как завершатся все синхронные операции.
  3. setTimeout(() => { console.log(3) }, 0) – setTimeout с нулевой задержкой помещает свой коллбэк в очередь макрозадач. Он будет выполнен после всех синхронных операций, а также после выполнения всех микрозадач, включая промисы.
  4. promise1.then(res => { console.log(res) }) – Этот обработчик будет вызван после того, как основной стек вызовов (call stack) очистится. Он является микрозадачей и будет выполнен до следующей макрозадачи, то есть до setTimeout.
  5. console.log('end'); – Это последняя синхронная операция, поэтому 'end' выводится перед тем, как выполняются асинхронные задачи.
  • Question 4: start , 1 , end
  1. console.log('start'); – Это синхронный вызов, поэтому сначала выводится 'start'.
  2. const promise1 = new Promise((resolve, reject) => { console.log(1) }) – Здесь создается новый промис. Функция-исполнитель (executor), переданная в конструктор промиса, является синхронной, поэтому сразу выводится 1. Однако важно заметить, что промис promise1 никогда не переходит в состояние "resolved" или "rejected", потому что внутри функции-исполнителя не вызывается ни resolve, ни reject.
  3. promise1.then(res => { console.log(2) }) – Поскольку promise1 не разрешается (не вызывается resolve), обработчик .then() не будет выполнен. Таким образом, console.log(2) внутри .then() не выполняется.
  4. console.log('end'); – Это синхронная операция, она выполняется последней из синхронного кода, выводя 'end'.
  • Question 5: start , middle, 1 , end и success
  1. console.log('start'); – Это синхронная операция, поэтому первым делом выводится 'start'.
  2. const fn = () => ... – Это объявление функции, которое само по себе не выполняет никаких операций, так что оно не влияет на вывод в консоль.
  3. console.log('middle'); – Следующая синхронная операция, выводит 'middle'.
  4. fn().then(res => { console.log(res) }) – Здесь вызывается функция fn, которая возвращает промис. При создании этого промиса сразу выполняется его executor-функция, выводя 1. Промис разрешается (resolve) со значением 'success', но обработчик .then() будет выполнен только после завершения всех синхронных операций.
  5. console.log('end'); – Это последняя синхронная операция, выводит 'end'.
  6. После выполнения всех синхронных операций, JavaScript обрабатывает микрозадачи, в том числе обработчики промисов. Ваш обработчик .then() теперь активируется и выводит 'success'.
  • Question 6: start , end , 1 и 2
  1. console.log('start'); – Это синхронная операция, поэтому первым делом выводится 'start'.
  2. Promise.resolve(1).then((res) => { console.log(res) }) – Создается промис, который сразу переходит в состояние "resolved" с результатом 1. Однако, обработчик .then() не вызывается сразу; он добавляется в очередь микрозадач и будет выполнен после завершения всех текущих синхронных операций.
  3. Promise.resolve(2).then((res) => { console.log(res) }) – Аналогично предыдущему шагу, создается промис, который сразу переходит в состояние "resolved" с результатом 2, и обработчик .then() также добавляется в очередь микрозадач
  4. console.log('end'); – Последняя синхронная операция, выводит 'end'.
  5. После выполнения всех синхронных операций, выполняются микрозадачи, добавленные в очередь. Сначала выполняется обработчик промиса с результатом 1, затем – с результатом 2.

Итак, порядок выполнения: 'start', 'end' (синхронные операции), затем '1' и '2' (асинхронные операции, обработчики промисов).

  • Question 7: start , end , resolve и setTimeout
  1. console.log('start'); – Это синхронный вызов, поэтому первым делом выводится 'start'.
  2. setTimeout(() => { console.log('setTimeout') })setTimeout добавляет свою функцию обратного вызова в очередь макрозадач. Это означает, что она будет выполнена после всех текущих синхронных операций и всех микрозадач, назначенных перед ней.
  3. Promise.resolve().then(() => { console.log('resolve') }) – Создается промис, который сразу переходит в состояние "resolved". Его обработчик .then() добавляется в очередь микрозадач, которые выполняются до начала следующей фазы событийного цикла и до макрозадач, таких как setTimeout.
  4. console.log('end'); – Это синхронная операция, поэтому она выполняется следующей, выводя 'end'.
  5. После завершения всех синхронных операций, JavaScript обрабатывает микрозадачи. Обработчик .then() от Promise.resolve() активируется, выводя 'resolve'.
  6. Наконец, когда микрозадачи завершены, выполняется функция обратного вызова из setTimeout, выводя 'setTimeout'.

Таким образом, порядок выполнения: start, end, resolve, setTimeout. Это демонстрирует разницу между микрозадачами (промисы) и макрозадачами (такими как setTimeout), которые обрабатываются в разных фазах событийного цикла JavaScript.

  • Question 8: 1, 2, 4, timeStart, timeEnd, success
  1. const promise = new Promise((resolve, reject) => { ... }) – Создается новый промис, и сразу выполняется функция-исполнитель (executor function) промиса.
  2. console.log(1); – Сначала выводится 1, так как это первая операция в функции-исполнителе.
  3. setTimeout(() => { console.log("timerStart"); resolve("success"); console.log("timerEnd"); }, 0); – Этот вызов setTimeout ставит функцию обратного вызова в очередь макрозадач. Она будет выполнена после всех текущих синхронных операций и микрозадач.
  4. console.log(2); – Затем выводится 2, так как это следующая синхронная операция в функции-исполнителе промиса.
  5. console.log(4); – Следующая синхронная операция вне промиса, выводит 4.
  6. После выполнения всех синхронных операций, JavaScript обрабатывает микрозадачи и макрозадачи. setTimeout является макрозадачей, поэтому его функция обратного вызова выполняется теперь, сначала выводя "timerStart", затем "timerEnd".
  7. Когда setTimeout вызывает resolve("success") внутри своего обратного вызова, состояние промиса меняется на "resolved", и соответствующий обработчик .then() добавляется в очередь микрозадач.
  8. Обработчик .then((res) => { console.log(res); }) от promise активируется после выполнения текущей макрозадачи (setTimeout), выводя 'success'.

Таким образом, порядок выполнения: 1, 2, 4 (синхронные операции), затем timerStart, timerEnd (внутри setTimeout, макрозадача), и в конце success (в обработчике .then() от promise).

  • Question 9: timer1, promise1, timer2
  1. setTimeout(() => { ... }, 0) для timer1 и timer2 – Оба setTimeout добавляют свои функции обратного вызова в очередь макрозадач. Поскольку они оба имеют задержку 0, они будут выполнены в порядке их добавления после завершения всех текущих синхронных операций и микрозадач.
  2. Поскольку timer1 добавляется в очередь первым, его функция обратного вызова выполняется первой. Выводится 'timer1'.
  3. Внутри обратного вызова timer1 создается промис promise1 и его обработчик .then(() => { console.log('promise1') }). Обработчик .then() промиса является микрозадачей и будет выполнен сразу после завершения текущей макрозадачи, но до следующей макрозадачи.
  4. После завершения обратного вызова timer1 и перед началом обратного вызова timer2, выполняется микрозадача promise1. Выводится 'promise1'.
  5. Затем выполняется обратный вызов timer2, выводя 'timer2'.

Таким образом, порядок выполнения: timer1 (первая макрозадача), promise1 (микрозадача внутри timer1), timer2 (вторая макрозадача). Это демонстрирует, как JavaScript обрабатывает макрозадачи и микрозадачи: микрозадачи всегда выполняются между макрозадачами.

  • Question 10: start, end, promise1, timer1, promise2, timer2
  1. console.log('start'); – Это синхронная операция, поэтому выводится сначала 'start'.
  2. const promise1 = Promise.resolve().then(() => { ... }) – Создается промис, который немедленно переходит в состояние "resolved". Его обработчик .then() добавляется в очередь микрозадач и будет выполнен после завершения всех синхронных операций и перед любыми макрозадачами.
  3. const timer1 = setTimeout(() => { ... }, 0)setTimeout добавляет свою функцию обратного вызова в очередь макрозадач. Эта функция будет выполнена после всех микрозадач, включая те, что уже есть в очереди.
  4. console.log('end'); – Это следующая синхронная операция, выводит 'end'.
  5. Теперь выполняется микрозадача от promise1, выводя 'promise1'. Внутри обработчика .then() этого промиса запускается timer2, который добавляется в очередь макрозадач.
  6. После этого выполняется макрозадача от timer1, выводя 'timer1'. Внутри обратного вызова timer1 создается promise2, и его обработчик .then() добавляется в очередь микрозадач.
  7. Затем выполняется микрозадача от promise2, выводя 'promise2'.
  8. И, наконец, выполняется timer2, который был добавлен в очередь макрозадач в обработчике .then() от promise1. Выводится 'timer2'.

Итак, порядок выполнения: start, end (синхронные операции), promise1 (микрозадача), timer1 (макрозадача), promise2 (микрозадача, созданная внутри обратного вызова timer1), и timer2 (макрозадача, созданная в обработчике .then() от promise1).

  • Question 11: 1, 2, 3, 4
  1. console.log(1); – Это синхронная операция, поэтому первым делом выводится '1'.
  2. Вызов asyncFunc();:
    • Вход в функцию asyncFunc.
    • console.log(2); – Синхронная операция внутри asyncFunc, выводит '2'.
    • await Promise.resolve();await приостанавливает выполнение оставшейся части функции asyncFunc до тех пор, пока промис не разрешится (в данном случае моментально). Однако, оставшаяся часть функции после await (включая console.log(4);) будет выполнена как микрозадача, что означает, что она отложена до того, как текущий стек вызовов (состоящий из синхронных вызовов) очистится.
  3. console.log(3); – Следующая синхронная операция, выполняется третьей, выводит '3'.
  4. После завершения текущего стека вызовов, выполняется оставшаяся часть функции asyncFunc (после await), то есть console.log(4);, выводя '4'.

Таким образом, порядок выполнения: 1, 2, 3, 4. Это демонстрирует, как await в асинхронной функции откладывает выполнение кода после await до следующей микрозадачи, позволяя остальным синхронным операциям выполниться сначала.

  • Question 12: 1
  1. Promise.resolve(1) – Создает промис, который немедленно разрешается со значением 1.
  2. .then(2) – Здесь аргументом метода .then является число 2, а не функция. В метод .then должна быть передана функция, чтобы она была вызвана при разрешении промиса. Поскольку здесь передана не функция, этот .then просто пропускает свое значение (в данном случае 1 от предыдущего промиса) дальше по цепочке без изменений.
  3. .then(Promise.resolve(3)) – Аналогично предыдущему .then, здесь в качестве аргумента передается промис, а не функция. Поэтому этот вызов .then также не изменяет значение и просто передает его дальше. Это означает, что 1 продолжает передаваться по цепочке.
  4. .then(console.log) – В этом методе .then в качестве аргумента передается функция console.log. Эта функция будет вызвана с значением, переданным из предыдущего шага цепочки промисов, которое в данном случае равно 1.

Таким образом, выводится 1. Остальные вызовы .then в данной цепочке не влияют на результат, поскольку в них не передаются функции-обработчики.

  • Question 13: first, third, fifth, fourth, second
  1. console.log('first'); – Это синхронная операция, поэтому первым делом выводится 'first'.
  2. setTimeout(() => console.log('second'), 0);setTimeout добавляет свою функцию обратного вызова в очередь макрозадач, которая будет выполнена после всех текущих синхронных операций и микрозадач. Эта функция выводит 'second', но будет выполнена последней.
  3. new Promise((resolve, reject) => { console.log('third'); resolve(); }) – Создается промис, который немедленно переходит в состояние "resolved". В процессе создания промиса сразу выполняется функция, переданная в конструктор, поэтому выводится 'third'.
  4. .then(() => console.log('fourth')); – Обработчик .then() для промиса добавляется в очередь микрозадач и будет выполнен после завершения всех текущих синхронных операций, но до выполнения макрозадач (например, до функции из setTimeout). Эта функция выводит 'fourth'.
  5. console.log('fifth'); – Следующая синхронная операция, выводит 'fifth'.
  6. После выполнения всех синхронных операций, выполняются микрозадачи, включая обработчик .then() от промиса, который выводит 'fourth'.
  7. Наконец, выполняется функция из setTimeout, выводя 'second'.

Итак, порядок выполнения: first, third, fifth (синхронные операции), затем fourth (микрозадача), и в конце second (макрозадача).

  • Question 14: 2, 3, 5, 4, 1
  1. setTimeout(() => console.log("1"), 0); – Этот вызов setTimeout ставит функцию обратного вызова в очередь макрозадач, которая будет выполнена после всех текущих синхронных операций и микрозадач. Функция выводит "1", но будет выполнена в последнюю очередь.
  2. new Promise((resolve, reject) => { ... }) – Создается промис, и сразу выполняется его функция-исполнитель. Выводится "2". Затем выполняется цикл for, и когда i достигает 9999, вызывается resolve(). Несмотря на то что resolve() вызывается внутри цикла, обработчик .then() для этого промиса будет вызван только после того, как завершится выполнение всего синхронного кода в функции-исполнителе, включая вывод "3".
  3. console.log("3"); – Выводится как часть синхронного кода в функции-исполнителе промиса.
  4. console.log("5"); – Это следующая синхронная операция после создания промиса, выводит "5".
  5. .then(() => console.log("4")); – Обработчик .then() для промиса добавляется в очередь микрозадач. Он будет выполнен после завершения всех текущих синхронных операций, но до выполнения макрозадач, таких как setTimeout. Выводит "4".
  6. Наконец, выполняется функция обратного вызова из setTimeout, выводя "1".

Таким образом, порядок выполнения: 2, 3, 5 (синхронные операции внутри и вне промиса), затем 4 (микрозадача из обработчика .then() промиса), и в конце 1 (макрозадача из setTimeout).

  • Question 15: fail: error
  1. Promise.reject('error') – Создается промис, который немедленно переходит в состояние "rejected" с причиной отказа 'error'.
  2. .then(res => console.log('success:', res), err => console.log('fail:', err)) – Метод .then принимает две функции: первая вызывается, если промис выполнен успешно (res => ...), а вторая – если промис завершился с ошибкой (err => ...). Поскольку промис был отклонен (rejected), вызывается вторая функция, которая выводит 'fail: error'.

Таким образом, поскольку промис отклонен, вызывается обработчик ошибок, переданный в метод .then, и выводится сообщение об ошибке.

  • Question 16: 2, 1, 4, 3
  1. console.log(2); – Это первая синхронная операция, она выполняется и выводит 2.
  2. Вызов func();:
    • Вход в функцию func.
    • console.log(1); – Это синхронная операция внутри функции func, она выполняется и выводит 1.
    • await new Promise(resolve => setTimeout(resolve, 1000)); – Здесь функция func ожидает завершения промиса, который разрешится через 1 секунду (из-за setTimeout). Оператор await приостанавливает дальнейшее выполнение функции func до тех пор, пока не разрешится промис. Это означает, что код после await в функции func (в данном случае console.log(3)) будет выполнен позже, после разрешения промиса.
  3. console.log(4); – Это синхронная операция, выполняется после вызова func(), но до того, как промис в func() разрешится, выводит 4.
  4. После того, как таймер в await истекает (через 1 секунду), промис разрешается, и выполнение функции func продолжается. Выводится `3.

Таким образом, порядок выполнения: 2 (первая синхронная операция), 1 (выполнение внутри func до await), 4 (следующая синхронная операция), и 3 (после завершения ожидания в func).

  • Question 17: then1, then1.1, then2
  1. Promise.resolve() создает промис, который немедленно переходит в состояние "resolved".
  2. .then(() => { ... }) – Этот обработчик промиса вызывается после того, как начальный промис был разрешен. Внутри этого обработчика сначала выполняется console.log('then1');, выводя 'then1'.
  3. Promise.resolve().then(() => console.log('then1.1')); – Внутри первого обработчика .then создается еще один промис, который также немедленно переходит в состояние "resolved". Его обработчик .then(() => console.log('then1.1')) добавляется в очередь микрозадач и будет выполнен сразу после текущего микротаска (после того как текущий .then блок завершится, но до следующего .then блока).
  4. .then(() => console.log('then2')); – Этот обработчик .then добавляется в очередь микрозадач после первого обработчика .then и будет выполнен после него, но перед тем, как выполнится then1.1. Однако, поскольку then1.1 является микрозадачей, добавленной во время выполнения первого обработчика .then, он выполняется до второго обработчика .then. Таким образом, выводится 'then1.1'.
  5. После выполнения обработчика then1.1, выполняется второй обработчик .then, который выводит 'then2'.

Итак, порядок выполнения: сначала 'then1', затем 'then1.1' (как микрозадача, добавленная в первом .then), и в конце 'then2'.

  • Question 18: b, c, a
  1. setTimeout(() => console.log('a'), 0); – Эта функция ставит в очередь макрозадачу, которая будет выполнена после всех текущих микрозадач. Функция обратного вызова в setTimeout выводит 'a', но будет выполнена после всех микрозадач, так как setTimeout даже с нулевой задержкой не выполняется сразу.
  2. Promise.resolve().then(() => console.log('b')) – Создается промис, который немедленно переходит в состояние "resolved". Его обработчик .then() добавляется в очередь микрозадач и будет выполнен как только текущий стек вызовов очистится. Выводится 'b'.
  3. .then(() => console.log('c')) – Следующий обработчик .then() добавляется в очередь микрозадач сразу после первого обработчика .then(). Он будет выполнен после него, но до любых макрозадач, таких как setTimeout. Выводится 'c'.
  4. После завершения всех микрозадач начинается выполнение макрозадач. Функция обратного вызова из setTimeout выполняется, выводя 'a'.

Таким образом, порядок выполнения: сначала 'b' и 'c' (как микрозадачи от промисов), затем 'a' (как макрозадача от setTimeout).

  • Question 19: start, end, promise, setTimeout
  1. console.log('start'); – Это синхронная операция, поэтому она выполняется первой и выводит 'start'.
  2. setTimeout(() => console.log('setTimeout'), 0); – Здесь функция обратного вызова setTimeout добавляется в очередь макрозадач. Она будет выполнена после всех синхронных операций и микрозадач, несмотря на нулевую задержку.
  3. Promise.resolve().then(() => console.log('promise')); – Создается промис, который немедленно переходит в состояние "resolved". Обработчик .then() добавляется в очередь микрозадач и будет выполнен после завершения всех текущих синхронных операций, но перед макрозадачами.
  4. console.log('end'); – Это еще одна синхронная операция, которая выполняется после 'start', выводит 'end'.
  5. После завершения синхронных операций, выполняются микрозадачи. В данном случае, это обработчик .then() от Promise.resolve(), который выводит 'promise'.
  6. После того как микрозадачи завершены, выполняется функция обратного вызова из setTimeout, выводя 'setTimeout'.

Итак, порядок выполнения: сначала выполняются синхронные операции ('start' и 'end'), затем микрозадачи ('promise'), и в конце макрозадачи ('setTimeout').

  • Question 20: 4, 1, 2, 5, 3.
  1. console.log(4); – Сначала выполняется эта синхронная операция, выводя 4.
  2. Вызов test(); – Вызывается асинхронная функция test.
    • Внутри test, console.log(1); сначала выводит 1.
    • await async function() { console.log(2) }(); – Здесь вызывается анонимная асинхронная функция. await ожидает её выполнения. Эта функция сразу же выводит 2, так как она является асинхронной, но её выполнение не приостанавливает текущий поток выполнения.
    • Выполнение функции test приостанавливается на await.
  3. console.log(5); – После вызова test выполняется эта синхронная операция, выводя 5.
  4. Затем, после завершения асинхронной анонимной функции и await, продолжается выполнение функции test, выводя 3.