Класс, который обычно реализует Future
и на который вы хотите посмотреть, является DefaultPromise
.
Содержит изменяемое состояние, которое обновляется по завершении Future.
- Если вы звоните
onComplete
, и он уже завершен, он просто сразу же планирует ваш обратный вызов с результатом. Обратный вызов нигде не записан.
- Если вы позвоните
onComplete
, пока результат еще не доступен, обратный вызов добавляется в список «слушателей».
- Когда результат становится доступным (кто-то вызывает
complete
по обещанию), тогда все слушатели планируются для запуска с этим результатом, и список слушателей удаляется (внутреннее состояние изменяется на «завершено с этим результатом»)
Это означает, что ваша цепочка обратных вызовов строится только до тех пор, пока «восходящее будущее» не будет завершено. После этого все решается и собирается.
«Список слушателей» выше - это немного упрощение. Особое внимание уделяется тому, чтобы эти слушатели не заканчивали ссылками друг на друга, в частности, чтобы разорвать циклы ссылок, которые не позволили бы сбору мусора работать при рекурсивном построении фьючерсов. Очевидно, это было действительно проблемой в более ранних версиях.
Проблема утечек решается путем автоматического разрыва этих цепочек обещаний, чтобы обещания не ссылались друг на друга в длинной цепочке. это
позволяет каждому обещанию быть собраны индивидуально. Идея состоит в том, чтобы "сгладить"
цепочка обещаний, так что вместо каждого обещания, указывающего на его
сосед, вместо этого они прямо указывают на обещание в корне
цепь. Это означает, что ссылка только на корневое обещание, и все
другие обещания доступны для сбора мусора, как только их нет
больше ссылается на код пользователя.