Цепочка промисов

16-06-24 17:56:54


Image for the Цепочка промисов

Что такое цепочка промисов?

Цепочка промисов — это процесс связывания нескольких промисов так, чтобы каждый выполнялся последовательно, а вывод одного промиса становился вводом для следующего. Это достигается с помощью метода .then(), который возвращает новый промис, позволяя плавно выполнять асинхронные операции.

Цепочка промисов предоставляет несколько преимуществ по сравнению с традиционными подходами на основе коллбеков:

  • Читаемость: Код, написанный с использованием цепочки промисов, обычно более читаем и легче для понимания, чем глубоко вложенные коллбеки.
  • Обработка ошибок: Промисы позволяют централизованно обрабатывать ошибки с помощью метода .catch().
  • Последовательное выполнение: Промисы естественно поддерживают последовательное выполнение асинхронных операций.

Пример цепочки промисов

Рассмотрим тот же сценарий, где нам нужно получить данные пользователя, получить посты этого пользователя, а затем получить комментарии к каждому посту. Используя промисы, код будет выглядеть так:

function getUser(userId) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Пользователь получен');
resolve({ id: userId, name: 'John Doe' });
}, 1000);
});
}

function getPosts(userId) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Посты получены');
resolve([
{ postId: 1, title: 'Пост 1' },
{ postId: 2, title: 'Пост 2' }
]);
}, 1000);
});
}

function getComments(postId) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Комментарии получены');
resolve([
{ commentId: 1, text: 'Комментарий 1' },
{ commentId: 2, text: 'Комментарий 2' }
]);
}, 1000);
});
}

// Цепочка промисов
getUser(1)
.then(user => {
return getPosts(user.id);
})
.then(posts => {
return Promise.all(posts.map(post => {
return getComments(post.postId)
.then(comments => {
console.log(`Комментарии к посту ${post.postId}`, comments);
});
}));
})
.catch(err => {
console.error('Ошибка:', err);
});

Как работает цепочка промисов

В приведенном выше примере мы связываем промисы вместе с помощью метода .then():

  • getUser(1) возвращает промис, который разрешается с данными пользователя.
  • Следующий метод .then() принимает данные пользователя и вызывает getPosts(user.id), который возвращает промис, разрешающийся с постами.
  • Следующий метод .then() принимает посты и использует Promise.all(), чтобы дождаться получения всех комментариев для каждого поста.

Метод .catch() в конце обеспечивает захват и обработку любых ошибок в цепочке.

Продвинутая Цепочка Промисов

Цепочку промисов можно расширить для обработки более сложных сценариев. Например, если нам нужно обрабатывать ошибки на разных стадиях или выполнять дополнительные асинхронные операции, мы можем вставить больше блоков .then() и .catch() по мере необходимости.

Пример с дополнительной обработкой ошибок:

getUser(1)
.then(user => {
return getPosts(user.id);
})
.then(posts => {
return Promise.all(posts.map(post => {
return getComments(post.postId)
.then(comments => {
console.log(`Комментарии к посту ${post.postId}`, comments);
})
.catch(err => {
console.error(`Ошибка при получении комментариев к посту ${post.postId}:`, err);
});
}));
})
.catch(err => {
console.error('Ошибка:', err);
});

В этом примере мы специально обрабатываем ошибки для получения комментариев, сохраняя общий обработчик ошибок для всей цепочки.