.then() — JavaScript — Дока
- Кратко
- Как пишется
- Как понять
- На практике
- Николай Лопин советует
💡
Эта статья связана с понятием Promise.
Кратко
Скопировано
Метод then
используют, чтобы выполнить код после изменения состояния промиса.
Метод принимает два аргумента:
on
— функция-колбэк, которая будет вызвана при переходе промиса в состояние «успех»Fulfill fulfilled
. Функция имеет один параметр, в который передаётся результат выполнения операцииon
— функция-колбэк, которая будет вызвана при переходе промиса в состояние «ошибка»Reject rejected
. Функция имеет один параметр, в который передаётся информация об ошибке
Всегда возвращает новый промис.
Как пишется
Скопировано
// getPasswords() — асинхронная функция, которая возвращает промисgetPasswords(). then( function (result) { // что-то делаем с результатом операции console.log('Все пароли:' + result) }, function (err) { // обрабатываем ошибку console.error(err.message) })
// getPasswords() — асинхронная функция, которая возвращает промис
getPasswords().then(
function (result) {
// что-то делаем с результатом операции
console.log('Все пароли:' + result)
},
function (err) {
// обрабатываем ошибку
console.error(err.message)
}
)
Как понять
Скопировано
Обработка асинхронных операций через промис и then
очень похожа на работу с колбэками.
Так как then
всегда возвращает новый промис, то его удобно использовать для построения последовательностей асинхронных операций:
// запросим через API список домов из Игры престолов. Метод `fetch` возвращает промисfetch('https://www. anapioficeandfire.com/api/houses') .then(function (response) { // выполнится, когда от API придет ответ // запустим асинхронную операцию парсинга JSON из ответа сервера return response.json() // вернем из обработчика промис, к которому добавим then }) .then(function (houses) { // выполнится, когда JSON распарсится return fetch(houses[0].overlord) // запросим данные о сюзерене этого дома }) .then(function (response) { // выполнится, когда от API придет ответ return response.json() }) .then(function (overlord) { console.log(overlord.name) })
// запросим через API список домов из Игры престолов. Метод `fetch` возвращает промис
fetch('https://www.anapioficeandfire.com/api/houses')
.then(function (response) {
// выполнится, когда от API придет ответ
// запустим асинхронную операцию парсинга JSON из ответа сервера
return response.json() // вернем из обработчика промис, к которому добавим then
})
.then(function (houses) {
// выполнится, когда JSON распарсится
return fetch(houses[0]. overlord) // запросим данные о сюзерене этого дома
})
.then(function (response) {
// выполнится, когда от API придет ответ
return response.json()
})
.then(function (overlord) {
console.log(overlord.name)
})
В коде выше, каждый вызов then
привязан к результату предыдущей операции. Такой код читается почти как синхронный.
На практике
Скопировано
Николай Лопин советует
Скопировано
🛠 then
в индустрии используется только для обработки успешного завершения операции, в варианте с одним аргументом:
getPasswords().then(function (result) { // что-то делаем с результатом операции console.log(`Все пароли: ${result}`)})
getPasswords().then(function (result) {
// что-то делаем с результатом операции
console.log(`Все пароли: ${result}`)
})
Для обработки ошибок используют метод catch
. Такие цепочки читаются лучше:
getPasswords() .then(function (result) { console.log(`Все пароли: ${result}`) }) .catch(function (error) { console.log(`Ошибка: ${error.message}`) })getPasswords() .then(function (result) { console.log(`Все пароли: ${result}`) }) .catch(function (error) { console.log(`Ошибка: ${error.message}`) })
Если вы нашли ошибку, отправьте нам пул-реквест!
Во время отправки формы что-то пошло не так. Попробуйте ещё раз?
←
Promise
ctrl + alt + ←
→
.catch
ctrl + alt + →
Promise — отложенные и асинхронные вычисления
Promise(Обещание) — это объект который содержит будущее значение асинхронной операции. Например, если вы запрашиваете некоторые данные с сервера, промис обещает нам получить эти данные, которые мы сможем использовать в будущем.
Вначале промис имеет статус pending
(«ожидание»), затем – одно из: fulfilled
(«выполнено успешно») или rejected
(«выполнено с ошибкой🙅♂️»).
Pending
- Промис ожидает, если результат не готов. То есть, ожидает завершение чего-либо (например, завершения асинхронной операции).Fulfilled
- Промис решен, если результат доступен. То есть, что-то завершило свое выполнение(например, асинхронная операция) и все прошло успешно.Rejected
- Промиc отклонен, если произошла ошибка в процессе выполнения.
Видео
Создание промиса
Объект Promise
создается🏗️ при помощи ключевого🗝️ слова new и своего конструктора.
Конструктор Промисов принимает один аргумент, обратный вызов, также известный как исполнительная функция⚙️, которая принимает 2 обратных вызова,
и reject
.
Исполнительная функция⚙️ выполняется сразу же после создания🏗️ промиса. Промис становится выполненным при помощи вызова resolve()
, а отклоненным при помощи reject()
.
const promise = new Promise((resolve, reject) => {
if (allWentWell) {
resolve('Все прошло отлично!')
} else {
reject('Что-то пошло не так')
}
})
resolve()
и reject()
Чтобы снабдить функцию⚙️ функционалом⚙️ обещаний, нужно просто вернуть в ней объект Promise
:
function myAsyncFunction(url) {
return new Promise((resolve, reject) => {
//код функции
})
}
Использование промиса
Промисы используются при помощи методов then()
и catch()
.
then
Метод then
используется для запуска функций⚙️ при положительном и отрицательном результате промиса.
Синтаксис📖 метода then
:
promise. then(
function (result) {
/* обработает успешное выполнение */
},
function (error) {
/* обработает ошибку */
}
)
Первый 1️⃣ аргумент метода then
– функция⚙️, которая выполняется, когда промис переходит в состояние «выполнен успешно», и получает результат.
Второй аргумент then
– функция⚙️, которая выполняется, когда промис переходит в состояние «выполнен с ошибкой🙅♂️», и получает ошибку🙅♂️.
Пример метода then
:
let promise = new Promise(function (resolve, reject) {
setTimeout(() => resolve('done!'), 1000)
})// resolve запустит первую функцию, переданную в .then
promise.then(
result => alert(result), // выведет "done!" через одну секунду
error => alert(error) // не будет запущена
)
А в случае ошибки🙅♂️ в промисе – выполнится вторая:
let promise = new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('Whoops!')), 1000)
})// reject запустит вторую функцию, переданную в . then
promise.then(
result => alert(result), // не будет запущена
error => alert(error) // выведет "Error: Whoops!" спустя одну секунду
)
Если нужно вывести только результат успешного выполения, то в then
можно передать только одну функцию⚙️:
let promise = new Promise(resolve => {
setTimeout(() => resolve('done!'), 1000)
})promise.then(alert) // выведет "done!" спустя одну секунду
catch
Для отлова ошибок🙅♂️ используется метод catch
. Его можно использовать вместо метода then
для вывода сообщений💬 об ошибке🙅♂️.
Синтаксис📖 метода catch:
let promise = new Promise((resolve, reject) => {
setTimeout(() => reject(new Error('Ошибка!')), 1000)
})promise.catch(alert) // выведет "Error: Ошибка!" спустя одну секунду
promise.all
Этот метод берет массив промисов и возвращает🔄 🆕 новый промис, который будет выполненным, когда все промисы внутри массива выполнены или отклонен, как только встречается промис, который отклоняется.
Например:
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise1 выполнен')
}, 2000)
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise2 выполнен')
}, 1500)
})
Promise.all([promise1, promise2])
.then(data => console.log(data[0], data[1]))
.catch(error => console.log(error))
Здесь аргументом внутри then()
выступает массив, который содержит значения промисов в том же порядке, в котором они передавались в Promise.all()
.
Проблемы?
Пишите в Discord или телеграмм чат, а также подписывайтесь на наши новости
Вопросы:
Как называется метод который вызывается при успешном выполнении промиса?
reject
resolve
Каким методом можно проверить выполнение всех промисов в массиве?
promise. all
promise.race
Какой метод служит для отлова ошибок в промисах?
then
catch
Для того чтобы понять, на сколько вы усвоили этот урок, пройдите тест в мобильном приложении нашей школы по этой теме или в нашем телеграм боте.
Ссылки:
- MDN web docs
- Learn JavaScript
- Understanding Promises
Contributors ✨
Thanks goes to these wonderful people (emoji key):
Philipp Dvinyaninov 📖 | Dmitriy Vasilev 💵 | Resoner2005 🐛 🎨 🖋 | Navernoss 🖋 🐛 🎨 |
Почему .then() работает без промисов в JavaScript?
Метод then() возвращает обещание. См. документы.
Промис имеет метод обработчика. Как только обещание выполнено или отклонено, соответствующая функция-обработчик будет вызываться асинхронно. Поведение функции обработчика следует определенному набору правил, как указано здесь.
Давайте рассмотрим их один за другим. Вот код, который мы будем проверять бок о бок. Ничего особенного, просто цепочка обещаний, возвращающих значения.
пусть последовательность = новое обещание (функция (разрешить) { console.log('Назовите 1') решить(1) }) последовательность .тог(() => { console.log('Скажи 2') вернуть 2 }) .тог(() => { console.log('Произнесите 3') }) .тог(() => { console.log('Скажи 4') вернуть Promise.resolve(4) }) .тог(() => { вернуть новое обещание (функция (разрешить) { console.log('Произнесите 5') setTimeout(() =>{разрешить(5)}, 1000) }) })
- возвращает значение, обещание, возвращенное к этому времени, разрешается с возвращенным значением в качестве его значения;
В коде это Скажем 2
и ваш первоначальный вопрос. Когда значение возвращается, then()
возвращает обещание, которое разрешается с возвращенным вами значением.
- ничего не возвращает, обещание, возвращенное к тому времени, разрешается с неопределенным значением;
то же, что и выше.
- выдает ошибку, обещание, возвращенное к тому времени, отклоняется с выброшенной ошибкой в качестве значения;
то же, что и выше, за исключением того, что теперь then()
возвращает обещание, которое отклонено с вашей ошибкой.
- возвращает уже разрешенное обещание, обещание, возвращенное к тому времени, разрешается со значением этого обещания в качестве значения;
В коде это Скажем 4
, где обещание уже разрешено. Итак, теперь then()
возвращает обещание, которое разрешается со значением 4.
- возвращает уже отклоненное обещание, обещание, возвращенное к тому времени, отклоняется со значением этого обещания в качестве значения;
То же, что и выше, за исключением того, что теперь он отклоняется.
- возвращает другой ожидающий объект обещания, разрешение/отклонение обещания, возвращенного к этому времени, будет после разрешения/отклонения обещания, возвращенного обработчиком. Кроме того, значение обещания, возвращаемое к тому времени, будет таким же, как значение обещания, возвращаемое обработчиком.
В коде это Скажем 5
then()
вернет Promise с результатами вашего обещания, т. е. 5. Следует отметить одну вещь, которую я также недавно узнал (предложено @Bergi в комментариях), что метод then()
всегда создает и возвращает новое обещание еще до того, как обратные вызовы цепочки начали выполняться. Обратные вызовы, которые вы передаете , then()
просто сообщают обещанию значение/ошибку, с которой обещание должно разрешить/отклонить.
Итак, вот почему 9Цепочка 0019 then() работает, даже если вы специально не возвращаете новое обещание, потому что метод then()
всегда создает новое обещание за кулисами и отклоняет/разрешает это обещание с возвращенным вами значением.
then()
.javascript — путают с .then() в промисах
Задавать вопрос
спросил
Изменено 2 года, 5 месяцев назад
Просмотрено 156 раз
Я новичок в js и изучаю промисы. Я придумал этот код, который будет печатать разрешенные значения из каждой функции и вызывать новые функции, используя .then
функция входа() { вернуть новое обещание ((разрешить, отклонить) => { setTimeout(() => { разрешить ({имя пользователя: 'по умолчанию'}) }, 1000) }) } функция getVideos () { вернуть новое обещание ((разрешить, отклонить) => { setTimeout(() => { разрешить (['vid1', 'vid2']) },1000) }) } функция getDesc() { вернуть новое обещание ((разрешить, отклонить) => { setTimeout(() => { разрешить ('описание') }, 1000) }) } постоянный тест = логин () test. then (рез => { console.log(разрешение) получитьвидео() }) .тог(рес => { console.log(разрешение) получить описание() }) .затем(рез => console.log(рез))
Но я не получаю ожидаемого результата, я думал, что все операторы в .then()
должны быть выполнены и разрешены для перехода к следующему оператору .then()
. Но очевидно, что это не тот случай, поскольку я получаю в качестве вывода следующее:
{имя пользователя: 'по умолчанию'} неопределенный неопределенный
Но я ожидал, что вывод будет похож на этот —
{имя пользователя: 'по умолчанию} ['вид1', 'вид2'] описание
, пожалуйста, укажите, где я ошибаюсь. Любая помощь приветствуется, большое спасибо
- javascript
- асинхронный
- обещание
- разрешение
0
Вам нужно добавить return
внутрь ваших цепочек, когда вы вызываете эти функции. Например:
функция логин() { вернуть новое обещание ((разрешить, отклонить) => { setTimeout(() => { разрешить ({имя пользователя: 'по умолчанию'}) }, 1000) }) } функция getVideos () { вернуть новое обещание ((разрешить, отклонить) => { setTimeout(() => { разрешить (['vid1', 'vid2']) },1000) }) } функция getDesc() { вернуть новое обещание ((разрешить, отклонить) => { setTimeout(() => { разрешить ('описание') }, 1000) }) } постоянный тест = логин () test.then (рез => { console.log(разрешение) вернуть getVideos () }) .тог(рес => { console.log(разрешение) вернуть getDesc() }) .затем(рез => console.log(рез))
Это хорошее руководство: https://javascript.info/promise-chaining
3
Внесите несколько незначительных изменений:
const test = login() test.then (рез => { console.