Я читал о вложенных обещаниях и столкнулся с этой проблемой кодирования в учебниках. Может кто-нибудь объяснить порядок выполнения этого кода?
new Promise((resolve) => {
new Promise((res) => {
console.info("c");
resolve(3);
res(2);
}).then((response) => console.info(response))
}).then((res) => console.info(res));
Я запустил код, и вывод был:
c
2
3
Но я ожидал, что вывод должен быть таким:
c
3
2
потому что внешнее обещание разрешается первым, а внутреннее обещание разрешается позже.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Короче, это из-за заказа вы звоните .then.
new Promise((resolve) => {
new Promise((res) => {
console.info("c");
resolve(3);
res(2);
В приведенном выше коде мы вводим внешний конструктор, который немедленно вызывает внешнюю функцию. Затем это создает внутреннее обещание, вызывая внутреннюю функцию. Внутренняя функция регистрирует «c», затем разрешает внешнее обещание в 3, а затем разрешает внутреннее обещание в 2.
Итак, на данный момент у нас есть 2 выполненных промиса, но нет кода, который пытается что-то с ними сделать.
}).then((response) => console.info(response))
Закончив построение внутреннего обещания, мы вызываем .then внутреннее обещание. Поскольку обещание разрешено, микрозадача ставится в очередь для запуска.
}).then((res) => console.info(res));
Закончив построение внешнего обещания, мы вызываем .then на внешнем обещании. Поскольку обещание разрешено, микрозадача ставится в очередь для запуска.
Теперь мы закончили выполнение всего синхронного кода. Стек вызовов очищается, и выполняются микрозадачи. Они выполняются в порядке очереди, поэтому микрозадача, связанная с внутренним промисом, запускается первой, выходя из системы 2. Затем запускается оставшаяся микрозадача и выходит из системы 3.
В дополнение к ответу Николая вас, возможно, сбивает с толку повторное использование идентификатора «res». Первое использование во внутреннем промисе — это обратный вызов, когда он возвращает значение 2 в промис. Второе использование в последней строке находится в другой области и используется как имя параметра в .then() для внешнего промиса. Если вы замените оба использования «res» в последней строке на «outerPromiseResult», это может помочь прояснить ситуацию.
Начальная внешняя функция вызывает внутреннюю функцию, которая содержит вызов resolve(3) без немедленного возврата, за которым следует вызов res(2). Эти вызовы помещаются в очередь микрозадач для выполнения после очистки стека вызовов. Внутренняя функция должна завершиться до того, как внешняя функция сможет полностью завершиться. Следовательно, очередь микрозадач содержит:
res(2)resolve(3)
если вы действительно сделали что-то асинхронное, результат будет таким, как ожидалось, например. оберните ВЕСЬ код внутри внутреннего обещания в
setTimeout