По какой причине приостановлено выполнение контекста в модели eventloop?

#javascript #ecmascript-6 #specifications

Вопрос:

Предоставление кода мгновенно:

 setTimeout(() =gt; console.log("next macro")); /// next macro Promise.resolve().then(() =gt; gen.next()) /// microtask inside, #2 const gen = (function*(){  console.log("Hello");  yield; /// #3  console.log("World"); })(); gen.next(); console.log("main script has been ended"); /// #1 

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

Этот код содержит 2 макрозадачи и 1 микрозадачу. Вы знаете, что eventloop не будет выполнять микрозадачи до тех пор, пока макрозадача не будет завершена. Так как, когда макрозадача будет завершена #1, то микрозадача будет активна #2, и именно код внутри этой микрозадачи вернет нас в функцию генератора #3, и мы выполним console.log(«Мир»).

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

P. S Вы можете меня не понять, потому что я не знаю, как правильно выразить свою мысль.

Ответ №1:

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

Он выполняется всякий next() раз, когда вызывается генератором. Если этот вызов выполняется как часть макрозадачи, он все равно остается частью этой макрозадачи. Если этот вызов происходит как часть микрозадачи, он является частью этой микрозадачи. Стек вызовов фактически увеличился при возобновлении кода генератора и возвращается к коду, который его возобновил (как и в next() случае ).

Поскольку в вашем примере вы вызываете next() как синхронный код, так и then обратный вызов, он сначала выполняется как часть макрозадачи, а затем как часть микрозадачи. В этом смысле это ничем не отличается от вызова функции.

Комментарии:

1. Итак, в моем случае, когда я вызываю next() в микрозадаче, код, который выполняется после, также является микрозадачей. Верно?

2. Да, микрозадача завершается только тогда, когда стек вызовов становится пустым.