承诺,不要开火然后'如果发生错误

时间:2017-01-24 08:25:32

标签: promise redux

我正在尝试构建一个简单的CRUD应用程序。用户有一个个人资料页面,可以填写自己的字段并保存。我的问题是:

我使用axios进行http请求(在Redux应用程序中):

export const createCard = (data) => (dispatch) =>
    axios.post('/api/cards', data)
        .then(
            response => dispatch({
                type: actions.CREATE_CARD_SUCCESS,
                card: response.data
            })
            error => dispatch({
                type: actions.CREATE_CARD_FAILURE,
                message: error.message
            })
        )
        .then(() => /* do something here, if no error occur */);

请求成功完成后,我想在then方法中做一些事情。但即使发生错误,它也会一直触发

这可以这样实现:

export const createCard = (data) => (dispatch) =>
    axios.post('/api/cards', data)
        .then(
            response => {
                dispatch({
                    type: actions.CREATE_CARD_SUCCESS,
                    card: response.data
                });
            },
            error => {
                dispatch({
                    type: actions.CREATE_CARD_FAILURE,
                    message: error.message
                });
                return error;
            }
        )
        .then(error => {
            if (!error) {
                /* do something here, if no error occur */
            }
        });

但它太多样板了。

在这种情况下,Jquery.ajax很方便。

$.ajax()
    .done()
    .fail()
    .always()
    .then(() => { /** this callback will be fired if no error occur **/})

如何在axios中模拟此行为或获取api?

2 个答案:

答案 0 :(得分:2)

您似乎有一个承诺拒绝处理程序,它处理拒绝并意外地将承诺从拒绝转回到已解决,因此即使发生错误也会调用您的后续.then()处理程序。

使用.catch()或第二次回调.then()创建承诺错误处理程序时:

p.then(result => {
    // do something with result here
}, err => {
    console.err(err);
}).then(result => {
    // this will always get fired because you "ate" the error in the previous catch handler
});

并且,您在不重新抛出或未返回被拒绝的承诺的情况下处理错误,然后承诺基础结构认为您已“处理”了错误并且父承诺已解决(不再被拒绝)。因此,即使在链中较早发生错误,也会调用任何后续.then()个处理程序。

如果您想对错误执行某些操作(例如记录或执行其他逻辑),但您希望承诺保持拒绝,则必须重新抛出错误或返回被拒绝的承诺。这是使链条被拒绝的唯一方法。

虽然您的问题中的代码似乎缺少逗号,但看起来这应该是.then()处理程序的第二个参数,因此在拒绝承诺时会被调用:

       error => {
            dispatch({
                type: actions.CREATE_CARD_FAILURE,
                message: error.message
            });
            return error;
        }

由于您只执行正常的return error,这将更改要解析的承诺(不再被拒绝),从而调用以下.then()处理程序。

为了保证拒绝承诺,您可以重新抛出错误(使用符合ES6标准的承诺),或者您可以返回被拒绝的承诺(使用jQuery .then()处理程序或符合ES6标准的承诺):

       error => {
            dispatch({
                type: actions.CREATE_CARD_FAILURE,
                message: error.message
            });
            // keep the promise rejected
            return Promise.reject(error);
        }

注意:这与try / catch对常规同步代码的工作方式非常类似。当您执行catch()时,异常将被处理,除非您重新抛出异常,否则不会传播。承诺捕获处理程序也是如此。

答案 1 :(得分:1)

如果省略#include <stdio.h> #include <string.h> 回调中的错误处理程序,任何错误都将传播到下一个有一个错误(如果有)的回调。在链的末尾添加一个catch块,以便对整个链执行错误处理:

then