Интересный вопрос! Больше экспериментов.
Вспомогательная функция для читаемости:
const log = (value, returnPromise) => () => {
console.log(value);
if (returnPromise) return Promise.resolve();
};
Возвращает функцию, которая обычный console.log() с переданным значением. И если второй аргумент трушный, то вернёт отрезолвленный промис.
Эксперимент 1. «Застёжка-молния»Promise.resolve()
.then(log('a1'))
.then(log('a2'))
.then(log('a3'))
.then(log('a4'))
.then(log('a5'))
.then(log('a6'))
;
Promise.resolve()
.then(log('b1'))
.then(log('b2'))
.then(log('b3'))
.then(log('b4'))
.then(log('b5'))
.then(log('b6'))
;
Выводит поочередные a1 b1 a2 b2 a3 b3 ...
Эксперимент 2. «Отстаём на 2»
Единственное отличие: в первом А возвращаем отресолвленный промис.
Promise.resolve()
.then(log('a1', true))
.then(log('a2'))
.then(log('a3'))
.then(log('a4'))
.then(log('a5'))
.then(log('a6'))
;
Promise.resolve()
.then(log('b1'))
.then(log('b2'))
.then(log('b3'))
.then(log('b4'))
.then(log('b5'))
.then(log('b6'))
;
Выводит
a1 b1 b2 b3 a2 b4 a3 b5 a4 b6 a5 a6
А-шки после 1-й отстают на 2, пропустив вперёд b2 и b3.
Очередь микрозадач работает как FIFO буфер: первый пришёл, первый ушёл.
Цепочка из
then()
выполняется асинхронно. После выполнения очередного, создаётся следующий microtask. Несколько цепочек, как видно из 1-го эксперимента, выполняются параллельно-пошагово, «молнией».
Возврат созданного выполненного промиса, и ожидание его разрешения вызывает задержку в очереди микрозадач на 2 шага. Пока не совсем понимаю, почему именно на 2. Один – это ожидание ресолва промиса, который вернул
then()
. Второй – ?