Создание обещания с помошью конструктора new Promise()
В предыдущих статьях об обещаниях в JavaScript мы использовали метод fetch из fetch API, который возвращает объект класса Promise. А для получения результата обещания мы использовали метод then(). И в большинстве случаев, мы будем использовать библиотеки, которые выполняют некую работу и возвращают нам результат в виде объекта Promise. Однако в будущем может возникнуть необходимость в создании собственных javascript-промисов, в которых, нужно будет определять обработчики для случаев выполнения и отклонения обещания.
Для создания объекта обещания, используется конструктор Promise (resolver),
где resolver - метод, который принимает 2 аргумента: resolve (разрешить)
и reject (отклонить).
Допустим, мы хотим создать функцию, которая генерирует случайное число от 1 до
10 и возвращает обещание. Если число равно 5 или меньше, то мы говорим что
обещание выполнено (resolve) (это означает, что операция прошла
успешно). Если число равно 6 или больше, мы отклоняем (reject) обещание
(операция не увенчалась успехом).
function genRandNum () {
return new Promise(function (resolve, reject) {
var randNum = Math.floor((Math.random() * 10) + 1)
if (randNum <= 5) {
resolve(randNum)
} else {
reject(randNum)
}
})
}
genRandNum().then(function(result) {
console.log('Успех: ' + result)
}).catch(function(error) {
console.log('Ошибка: ' + error)
})
Функция genRandNum () возвращает обещание с использованием конструктора
Promise. Функция обратного вызова resolver, которую мы передаем нашему
конструктору Promise, получает в качестве аргументов две функции – resolve
и reject.
Если randNum оказывается меньше или равен 5, мы считаем это успешным исходом
и, следовательно, вызываем метод resolve. Вы можете передать результат
выполнения обещания, в нашем случае это случайное числа, меньшее или равное 5,
методу resolve, в котором затем можно будет обратиться к этому результату,
используя метод then().
Аналогично, если число больше 5, мы считаем такой исход неудачным и вызываем метод reject с этим числом. Это приведет к тому, что метод catch() будет запущен с этим результатом-числом в качестве аргумента, который называется причиной отклонения.
Цепочка - один шаг за раз
Объединение нескольких методов then() позволяет вам дополнительно преобразовывать значения или выполнять дополнительные асинхронные задачи последовательно!
Это возможность становится действительно полезной, когда, например, нам необходимо выполнить некоторую последовательность действий для аутентификации пользователя, и если пользователь был успешно аутентифицирован, мы хотим вызвать другую последовательность действий, например для извлечения информации о профиле пользователя.
Описанный выше сценарий мог бы выглядеть примерно так:
// попытка аутентификации пользователя с id 5
fetch('/auth/5')
// передать объект ответа в функцию authenStatus
// для проверки возможности аутентификации пользователя
.then(authenStatus)
// если аутентификация прошла успешно, вызывать функцию loadProfile(),
передав ей в качестве аргумента имя пользователя
.then(loadProfile)
// вызвать в случае отсутствия пользователя с таким id
.catch(function (error) {
console.log(error)
})
function authenStatus (response) {
// если операция успешна, получить имя пользователя из ответа сервера
// и полагать, что обещание выполнено
if (response.status === 200) {
// response.user_name будет передано в последующий вызов `then`,
// в котором вызовется функция loadProfile
return Promise.resolve(response.user_name)
} else {
// ошибка аутентификации
return Promise.reject('Пользователь не может быть аутентифицирован')
}
}
function loadProfile (user_name) {
// извлечь и вывести в консоль данные профиля пользователя,
// переданные из вызова функции authenStatus
fetch('/userprofile/' + user_name)
.then(function (response) {
console.log(response.profile_data)
})
}
Пересмотрите этот пример несколько раз , чтобы понять, как все это работает вместе.
В приведенном выше примере есть две важные вещи, на которые стоит обратить внимание:
- Когда обещание выполнено, результат обещания автоматически передается как аргумент следующему методу then()
- Если обещание отклонено в authenStatus, метод catch будет немедленно выполнен, а метод then(loadProfile) будет пропущен вовсе.
На сегодня все! Всего доброго!
-
- Михаил Русаков
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.