Изучая сопрограммы в JavaScript, я не могу обернуться вокруг следующего примера :
coroutine(function* () {
let posts = yield fetchPosts();
let promises = posts.map(post => fetchComments(post));
let comments = yield Promise.all(promises);
displayComments(comments);
})
function coroutine(fn) {
let gen = fn();
let doNext = (data) => {
let next = gen.next(data);
if (!next.done) {
return next.value.then(doNext);
}
};
doNext();
}
Мне кажется, что при вызове coroutine
в приведенном выше примере, doNext
будет кумулятивно вызываться дважды.
Когда вызывается coroutine
, функция генератора останавливает выполнение в первой строке let posts = yield fetchposts();
; управление возвращается к функции coroutine
. В строке let next = gen.next(data);
управление передается обратно в функцию генератора.
Теперь, насколько я понимаю, fetchposts
в данный момент вернет Обещание, которое включает все сообщений. Следовательно, это будет первый запуск doNext
.
Второй запуск doNext
начнется, когда функция генератора остановит выполнение в строке let comments = yield Promise.all(promises);
; возвращение управления к функции coroutine
. В этот момент next.value.then(doNext)
больше не имеет смысла для меня. Я ожидаю, что next.value
будет обещанием, которое сможет разрешить комментарии.
А именно, Promises.all(promises)
передается обратно функцией генератора. Следовательно, это должно разрешиться, как только все комментарии будут извлечены post Promises.
Очевидно, я не вижу этого правильно, так как объяснение, которое я дал, не соответствует фактическому выполнению вызова. Что я вижу не так?