2017-01-24 15 views
0

私は単純なCRUDアプリケーションを構築しようとしています。ユーザーはプロフィールページを持っており、自分のフィールドを記入して保存することができます。私は(Reduxのアプリケーションで)HTTP要求のaxiosを使用してい約束、エラーが発生した場合は '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 
      }) 
     ) 
     .then(() => /* do something here, if no error occur */); 

し、要求が正常に終了した後、私は、この方法で何かをしたい私の質問です。

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でシミュレートするにはどうしたらよいですか?

答えて

1

あなたが拒絶反応を処理し、誤ってバック解決への拒否からの約束をオンハンドラを約束を拒否しているように見えるとしたがって、次の.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 
}); 

そして、あなたが再スローせずに、または拒否約束し、約束のインフラを返さずにエラーを処理:あなたは.catch()またはこのような.then()に2番目のコールバックとのいずれかとの約束のエラーハンドラを作成する

あなたがエラーを "処理"し、親の約束が解決された(拒否されなくなった)とみなします。したがって、チェーン内のエラーが以前に発生したとしても、その後に続く.then()ハンドラが呼び出されます。

エラーをログに記録したり他のロジックを実行したりしたいが、約束を却下したままにしておきたい場合は、エラーを再現するか、却下された約束を返さなければならない。それがチェーンを拒否する唯一の方法です。


あなたの質問のコードにコンマが欠落しているように見えますが、これは.then()ハンドラの第2引数であると考えられるとの約束を拒否された場合にこれと呼ばれますように、それが表示されます。

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

あなたは通常のreturn errorを実行しているだけなので、解決される(拒否されなくなりました)約束が変わり、次の.then()ハンドラが呼び出されます。

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

:拒否され、あなたは(ES6の標準の準拠した約束で)エラーを再スローすることができますかあなたは(jQueryの .then()ハンドラやES6の標準の準拠した約束のいずれかで)拒否された約束を返すことができるの約束を守るために

注:これは、通常の同期コードでtry/catchがどのように機能するかに非常に似ています。 catch()を実行すると、例外が処理され、再スローするまで例外は伝播しません。 promise catchハンドラと同じです。

+0

ok、私の知るように、jqueryのようなロジックを作る方法はありません。私ができることはエラーを投げることだけです。あなたのお返事の両方にお返事ありがとうございます。<3 –

+0

@SmikeNelipov - 「jQueryのような論理を作る」とはどういう意味ですか? – jfriend00

+0

jqueryは実行しません.failの後 '$ .ajax(... options).done()。fail()。then(。*コールバックがエラーをキャプチャした場合、このコールバックは起動しません。 /) ' –

1

thenコールバックでエラーハンドラを省略すると、エラーがあればそれを持つ次のコールバックに伝播されます。チェーン全体のエラー処理を実行するために、あなたのチェーンの最後にcatchブロックを追加します。

axios.post('/api/cards', data) 
    .then(response => { 
     dispatch({ 
      type: actions.CREATE_CARD_SUCCESS, 
      card: response.data 
     }); 
    }).then(() => { 
     // this block won't be executed if there is a post error 
    }).catch(error => { 
     // handle post error 
     dispatch({ 
      type: actions.CREATE_CARD_FAILURE, 
      message: error.message 
     }); 
     // if we wished to propagate the error to the caller, skipping 
     // subsequent then blocks, we could re-raise it here by throwing it: 
     //  throw error; 
    }).then(() => { 
     // this block will be executed after the catch handler unless 
     // it raises another error by throwing an exception 
    }); 
+0

私はコンポーネントで起動する必要がある場合は? 私は2つのページを持っています:1)アイテムのリスト、2)そのリストからのアイテムカード。 ユーザーはリストとカードからこのアイテムを削除できます。ユーザーがリストからアイテムを削除すると、リストからアイテムを削除したいだけです。 しかし、それがカードで起こるなら、私は成功した後に訪問/リストページをしたい。エラーがある場合は、このページにとどまり、ユーザーにエラーを表示します。 この場合、どうすればよいですか? –

+0

エラーを呑み込むには、実行する 'then'ブロックの前にcatchブロックを置きます。その後の 'then'はcatchハンドラの後に実行されます。 – teppic

+0

わかりやすくするために、回答にいくつかのコメントを追加しました。 – teppic

関連する問題