Перейти к содержимому

56. Создание своих промисов

JavaScript: Мозги. Урок: Создание своих промисов

Заголовок раздела «JavaScript: Мозги. Урок: Создание своих промисов»

Иллюстрация к уроку Промисы – это мощный инструмент для работы с асинхронными операциями в JavaScript. В этом уроке мы научимся создавать собственные промисы, чтобы лучше понимать, как они работают “под капотом” и расширить возможности управления асинхронным кодом.

Промис – это объект, представляющий собой результат асинхронной операции, которая может завершиться успешно (fulfilled) или с ошибкой (rejected). Промисы позволяют избежать “ада колбэков” и делают асинхронный код более читаемым и удобным для отладки.

Основная идея создания промиса заключается в использовании конструктора Promise. Конструктор принимает функцию-исполнитель (executor), которая, в свою очередь, принимает две функции: resolve и reject. resolve вызывается, когда асинхронная операция успешно завершена, а reject – когда произошла ошибка.

function myAsyncFunction(value) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (value > 0) {
resolve(`Операция успешно завершена, значение: ${value}`); // Вызываем resolve при успехе
} else {
reject("Ошибка: значение должно быть больше нуля."); // Вызываем reject при ошибке
}
}, 1000); // Имитация асинхронной операции (задержка в 1 секунду)
});
}
myAsyncFunction(5)
.then(result => {
console.log(result); // Выведет: Операция успешно завершена, значение: 5
})
.catch(error => {
console.error(error);
});
myAsyncFunction(-1)
.then(result => {
console.log(result); // Не выполнится, так как произошла ошибка
})
.catch(error => {
console.error(error); // Выведет: Ошибка: значение должно быть больше нуля.
});

В этом примере myAsyncFunction возвращает промис. Внутри промиса происходит имитация асинхронной операции с помощью setTimeout. В зависимости от значения value, вызывается либо resolve, либо reject.

Для обработки результатов промиса используются методы .then() и .catch().

  • .then() принимает функцию, которая вызывается, когда промис переходит в состояние “fulfilled”. Эта функция получает результат операции в качестве аргумента.
  • .catch() принимает функцию, которая вызывается, когда промис переходит в состояние “rejected”. Эта функция получает причину ошибки в качестве аргумента.

Создание собственных промисов часто используется для обертки API, которые изначально не используют промисы. Например, работа с XMLHttpRequest (XHR).

function getJSON(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.responseText));
} else {
reject(`Ошибка: статус ${xhr.status}`);
}
};
xhr.onerror = () => {
reject("Ошибка сети");
};
xhr.send();
});
}
getJSON('https://jsonplaceholder.typicode.com/todos/1')
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});

Многие современные библиотеки и фреймворки, такие как React, Angular, Vue.js активно используют промисы (или их альтернативы, такие как Observables) для управления асинхронными операциями, например, при запросе данных с сервера. Также, async/await – это синтаксический сахар над промисами, который делает асинхронный код еще более читаемым.

  • Промис имеет три состояния: pending (ожидание), fulfilled (успешно завершено) и rejected (отклонено).
  • Функция-исполнитель (executor) в конструкторе Promise выполняется сразу после создания промиса.
  • resolve и reject – это функции, которые контролируют переход промиса из состояния “pending” в “fulfilled” или “rejected” соответственно.
  • Методы .then() и .catch() используются для обработки результатов промиса.
  • Создание своих промисов позволяет обернуть существующий асинхронный код, не использующий промисы, и интегрировать его в систему, основанную на промисах.