В настоящее время я сталкиваюсь с довольно распространенной проблемой, когда дело доходит до асинхронного выполнения, обработки состояний и ада отступов.
Скажем, есть вызов REST, который запрашивает добавление пользовательской информации (user_info
) в пользователь, уведомить своих контактов об этом изменении и вернуть введенную или измененную информацию пользователя в ответ. Но пользователь object
знает все идентификаторы своих user_info
объектов только через отношение 1 к n.
Последовательность вызовов:
request -> saveUserInfo -> updateUser -> notifyContacts -> response
saveToDb
, updateUser
и notifyContacts
- это все функции, которые выполняют асинхронный побочный эффект и не могут быть просто скомпонованы, поскольку все они имеют разные входы и выходы и зависят от порядка выполнения.
Здесь приведено слабое представление заголовков функций
function saveUserInfo(payload): Promise<UserInfo[]> { /*...*/ }
function updateUser(user_id, user_infos): Promise<User> { /*...*/ }
function sendNotification(user, user_infos): Promise<void> { /*...*/ }
Чтобы написать этот обработчик запросов, я в настоящее время много работаю с mergeMap
, чтобы подписаться на внутренние наблюдаемые, которые выполняли текущее асинхронное действие. Это выглядело примерно так:
function handleRequest(payload, user_id) {
return saveUserInfo(payload).pipe(
mergeMap(user_infos =>
from(updateUser(user_id, user_infos)).pipe(
mergeMap(user =>
from(notifyContacts(user, user_infos)).pipe(map(() => user_infos))
)
)
)
)
}
Я не был удовлетворен этим решением, потому что в будущем будет добавлено больше логики c, и я знаю, что в какой-то момент это может стать громоздким.
Итак, я просмотрел документацию по Rx JS и, к сожалению, не нашел умного способа соединить эти асинхронные вызовы вместе гораздо более приятным способом. Самая большая проблема в том, что я не могу полностью сформулировать проблему здесь в нескольких словах, что могло бы привести меня к написанию этого вопроса.
Кто-нибудь знает лучшее решение этого вопроса? Я уверен, что должно быть что-то!
Желательно без вспомогательных функций и в чистом Rx JS.