Цепные обещания с редукторами действий в React - PullRequest
0 голосов
/ 09 января 2019

У меня есть метод, который запускает два HTTP-запроса к API для получения данных.

getServerDetails(this.props.match.params.id) //1
            .then(res => {
                this.props.getServerDetailsAction({ success: true, data: res.data })

                if (!_.isEmpty(res.data)) {
                    return getServerScomAlerts(res.data.ServerName) //2
                }
            })
            .catch((err) => { //3
                this.props.getServerDetailsAction({ success: false, error: err })
            })
            .then(res => {
                if (!_.isEmpty(res)) {
                    this.props.getServerScomAlertsAction({ success: true, data: res.data })
                }
            })
            .catch((err) => { //4
                this.props.getServerScomAlertsAction({ success: false, error: err })
            })
Методы

getServerDetails (1) и getServerScomAlerts (2) возвращают обещания. getServerScomAlerts (2) зависит от результата getServerDetails (1)

Проблема в том, что если ошибка возникает в getServerScomAlerts (2), то выполняется первый блок перехвата (3). Есть ли способ, как получить данные из первого метода (1) ( без доступа к хранилищу ) и одновременно перейти к соответствующему блоку перехвата (4), если произошла ошибка происходит?

Ответы [ 3 ]

0 голосов
/ 09 января 2019

Это действительно интересно с вашей проблемой, так как вы хотите сделать несколько действий, которые немного отличаются друг от друга только :). Я бы переписал как следует

const getServerScomAlertsAction = (success, props) => (res) => {
  success = success && !_.isEmpty(res);
  props.getServerScomAlertsAction(success ? { success, data: res.data } : { success, error: res });
};
const getServerDetailsAction = (success, props) => (res) => {
  props
    .getServerDetailsAction(success ? { success, data: res.data } : { success, error: res })
    .then(getServerScomAlertsAction(true, props))
    .catch(getServerScomAlertsAction(false, props));
};

getServerDetails(this.props.match.params.id)
  .then(getServerDetailsAction(true, this.props))
  .catch(getServerDetailsAction(false, this.props));
0 голосов
/ 09 января 2019

Это хороший пример использования метода .finally(), который в настоящее время находится в черновой спецификации в соответствии с MDN . Это позволяет удалить логику дублирования, запустив метод после того, как обещание разрешено или отклонено.

Как показано в примере MDN:

let isLoading = true;

fetch(myRequest).then(function(response) {
    var contentType = response.headers.get("content-type");
    if(contentType && contentType.includes("application/json")) {
      return response.json();
    }
    throw new TypeError("Oops, we haven't got JSON!");
  })
  .then(function(json) { /* process your JSON further */ })
  .catch(function(error) { console.log(error); /* this line can also throw, e.g. when console = {} */ })
  .finally(function() { isLoading = false; });

Если вы хотите использовать эту функцию прямо сейчас, вы можете рассмотреть возможность использования Bluebird для выполнения своего обещания, которое в некоторых случаях быстрее, и его должно быть легко обновить, поскольку метод стандартизирован

0 голосов
/ 09 января 2019

Примерно так может дать вам представление о том, как достичь своей цели. Вместо того, чтобы вкладывать потом, вы можете использовать async / await, и он ждет результата каждого вызова, прежде чем перейти к следующему:

export const actionCreators = {
    myFunc: (param1, param2) => async (dispatch, getState) => {
        try {
            const response1 = await fetch(param1);
            const data1 = await response.json();

            const response2 = await fetch(param2);
            const data2 = await response2.json();

        } catch (err) {
            console.log(err);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...