Давайте начнем с обещаний
В Javascript Promises - это общий шаблон, используемый для элегантной обработки асинхронного кода.Если вы не знаете, что это за обещания, начните там.Они выглядят примерно так:
todoService.getTodos() // this could be any async workload
.then(todos => {
// got returned todos
})
.catch(err => {
// error happened
})
Важные части:
todoService.getTodos() // returns a Promise
Давайте пока забудем о том, как работает getTodos()
.Важно знать, что многие библиотеки поддерживают Promises и могут возвращать обещания для асинхронных запросов, таких как http-запросы.
Объект Promise реализует два основных метода, облегчающих обработку результатов асинхронной работы.Эти методы .then()
и .catch()
.then
обрабатывает «успешные» результаты, а catch
- обработчик ошибок.Когда обработчик then
возвращает данные, это называется resolving
обещанием, а когда он выдает ошибку обработчику catch
, это называется rejecting
.
.then(todos => { // promise resolved with successful results })
.catch(err => { // promise rejected with an error })
Крутая вещьесть, then
и catch
также возвращают обещания, так что вы можете цепочка их так:
.then(todos => {
return todos[0]; // get first todo
})
.then(firstTodo => {
// got first todo!
})
Вот подвох: Обещания могут быть разрешены только ИЛИ ОДИН РАЗ
Это хорошо работает для таких вещей, как http-запросы, потому что http-запросы в основном выполняются один раз и возвращаются один раз (успех или ошибка).
Что происходит, когда вам нужен элегантный способ потоковая асинхронная передача данных?Подумайте видео, аудио, данные в режиме реального времени, сообщения в чате.Было бы здорово иметь возможность использовать обещания для настройки обработчика, который продолжает принимать данные при их потоковой передаче:
// impossible because promises only fire once!
videoService.streamVideo()
.then(videoChunk => { // new streaming chunk })
Добро пожаловать в реактивный шаблон
В двух словах: Обещаниячтобы асинхронизировать отдельные запросы, что такое Observables для асинхронной потоковой передачи данных.
Это выглядит примерно так:
videoService.getVideoStream() // returns observable, not promise
.subscribe(chunk => { // subscribe to an observable
// new chunk
}, err => {
// error thrown
});
Выглядит похоже на шаблон обещания, верно?Одно главное отличие между наблюдаемыми и обещаниями.Observables продолжают «излучать» данные в «подписку» вместо использования одноразовых обработчиков .then()
и .catch()
.
Клиентская библиотека Angular http возвращает наблюдаемые по умолчанию, даже если вы думаете, что http соответствует обещанию одноразового использованиякартина лучше.Но классная вещь в реактивном программировании (например, rxJS) состоит в том, что вы можете сделать наблюдаемые из других вещей, таких как события щелчка или любой произвольный поток событий.Затем вы можете объединить эти потоки вместе, чтобы сделать довольно интересные вещи.
Например, если вы хотите обновлять некоторые данные каждый раз, когда нажимается кнопка обновления И каждые 60 секунд, вы можете настроить что-то вроде этого:
const refreshObservable = someService.refreshButtonClicked(); // observable for every time the refresh button gets clicked
const timerObservable = someService.secondsTimer(60); // observable to fire every 60 seconds
merge(
refreshObservable,
timerObservable
)
.pipe(
refreshData()
)
.subscribe(data => // will keep firing with updated data! )
Довольно элегантный способ справиться со сложным процессом!Реактивное программирование - довольно большая тема, но этот - довольно хороший инструмент, чтобы попытаться визуализировать все полезные способы, которыми вы можете использовать observables для создания классных вещей.
примечание: этонепроверенный псевдокод, написанный только для иллюстрации