Промисы
Чашка — это абзац, #cup. Сначала на ней blank, и скрипт ставит waiting до того, как просит чай.
pour не возвращает напиток. Он возвращает промис. Через then ты просишь этот промис записать напиток позже. Строка под pour всё ещё говорит waiting. Строка получается waiting / lida tea.
Не та чашка, что только что
Прошлая страница передавала done в serve. serve вызывал функцию до возврата, поэтому журнал под ним уже был lida tea / poured. Там никто не ждал.
Здесь функция для then не выполняется на следующей строке. pour возвращается первым. Напиток появляется, когда этот скрипт уже закончился.
Три состояния
Промис pending, пока не решится. resolve выполняет его значением. reject отклоняет его причиной. then выполняется только при выполнении. catch выполняется только при отклонении. На этой странице нет таймера. Исполнитель вызывает resolve или reject сразу, а обработчики всё равно ждут конца скрипта.
📊 Три состояния
| Состояние | Что видно | Легко перепутать |
|---|---|---|
| pending | чашка всё ещё говорит waiting | напиток уже на чашке |
| fulfilled | then получает lida tea | catch тоже выполняется |
| rejected | catch получает no leaves | then получает напиток |
Исполнитель сейчас, обработчик нет
Функция для new Promise выполняется сразу. Поэтому resolve("lida tea") может случиться до возврата pour. Функция для then другая. Она встаёт в очередь. Строка после pour(...) выполняется, пока чашка говорит waiting.
Следующая строка всё ещё ждёт
pour("lida") кладёт промис в order. Чашка стала waiting. Журнал — это слово, не напиток.
function pour(order) {
return new Promise(function (resolve, reject) {
if (order === "") {
reject("no leaves");
return;
}
resolve(order + " tea");
});
}
let cup = document.getElementById("cup");
cup.textContent = "waiting";
let order = pour("lida");
console.log(cup.textContent);
Журнал — waiting. order — это промис. Это не текст lida tea.
then получает напиток
Вызови then с функцией. Эта функция получает значение, переданное в resolve. Она пишет напиток и журналирует его. Этот журнал не от следующей строки. Это журнал внутри then.
function pour(order) {
return new Promise(function (resolve, reject) {
if (order === "") {
reject("no leaves");
return;
}
resolve(order + " tea");
});
}
let cup = document.getElementById("cup");
pour("lida").then(function (drink) {
cup.textContent = drink;
console.log(cup.textContent);
});
Журнал — lida tea. Пустой текст до этого обработчика не доходит.
Нет листьев
pour("") вызывает reject("no leaves") и возвращается. catch получает эту причину. then не выполняется.
function pour(order) {
return new Promise(function (resolve, reject) {
if (order === "") {
reject("no leaves");
return;
}
resolve(order + " tea");
});
}
pour("").catch(function (reason) {
console.log(reason);
});
Журнал — no leaves.
Промис — не напиток
order.then — функция. По ней видно, что order промис, а не нужный текст. Сравнение промиса с "lida tea" было бы ложным, и этот фрагмент печатает только тип then.
function pour(order) {
return new Promise(function (resolve, reject) {
if (order === "") {
reject("no leaves");
return;
}
resolve(order + " tea");
});
}
let order = pour("lida");
console.log(typeof order.then);
Журнал — function.
Строка под чашкой
Скрипт ставит чашку в waiting и сразу кладёт это слово. then кладёт lida tea и склеивает два слова. Склейка внутри then, поэтому после скрипта, не на следующей строке.
<!DOCTYPE html>
<html>
<head>
<title>promised-cup — page</title>
</head>
<body>
<p id="cup">blank</p>
<p id="line">…</p>
<script>
function pour(order) {
return new Promise(function (resolve, reject) {
if (order === "") {
reject("no leaves");
return;
}
resolve(order + " tea");
});
}
let cup = document.getElementById("cup");
let seen = [];
cup.textContent = "waiting";
seen.push(cup.textContent);
pour("lida").then(function (drink) {
seen.push(drink);
cup.textContent = drink;
document.getElementById("line").textContent = seen.join(" / ");
});
</script>
</body>
</html>
Строка — waiting / lida tea. Waiting был сразу. lida tea пришёл в then. Слово blank исчезло. lida tea / poured — прошлая страница.
У стойки
- Поставь чашку в waiting, вызови
pour("lida")и сразу зажурналируй чашку. Журнал — waiting. - Поставь напиток на чашку внутри
then. Этот журнал — lida tea. - Вызови
pour("")и поймай причину черезcatch. Журнал — no leaves. - Прочитай
typeof order.then. Журнал — function. - Прочитай строку страницы: waiting / lida tea.
Промахи у стойки
Чашка говорит waiting, пока не выполнится then. Она не говорит poured.
- Ждать, что журнал под
pourбудет lida tea - Принять возвращённое значение за текст напитка
- Взять
thenдля пустого заказа и пропустить no leaves - Взять
catchдля lida и ждать no leaves - Прочитать строку как lida tea / poured
Оставь это
pourвозвращает промис, не текст lida tea- Следующая строка всё ещё журналирует waiting
thenполучает lida tea после этого скрипта- Пустой заказ отклоняется с no leaves, и
catchэто журналирует - Строка страницы — waiting / lida tea
🧠 Проверьте Свои Знания
Проверьте Свои Знания
Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему
📝 Инструкции
- Внимательно прочитайте каждый вопрос
- Выберите лучший ответ на каждый вопрос
- Вы можете пересдавать тест столько раз, сколько захотите
- Ваш прогресс будет показан вверху