Angular HttpPromise: `success` /` error`メソッドと `then`の引数の違い


177

AngularJS docによると$http、以下を返すための呼び出し:

標準のthenメソッドと2つのhttp固有のメソッド(successおよびerror)を持つpromiseオブジェクトを返します。その後、この方法は、二つの引数取り、成功エラーレスポンスオブジェクトに呼び出されるコールバックを。成功メソッドとエラーメソッドは単一の引数を受け取ります。この関数は、リクエストが成功または失敗したときにそれぞれ呼び出されます。これらの関数に渡される引数は、thenメソッドに渡される応答オブジェクトの非構造化表現です。

responseオブジェクトが1つのケースで分解されているという事実は別として、私は両者の違いがわかりません

  • の引数として渡される成功/エラーコールバック promise.then
  • promiseのpromise.success/ promise.errorメソッドの引数として渡されるコールバック

何かありますか?一見同一のコールバックを渡すこれらの2つの異なる方法のポイントは何ですか?

回答:


156

NBこの答えは実際には正しくありません。以下のコメントで指摘されているように、success()は元のプロミスを返します。 私は変更しません。編集はOPに任せます。


2つの主な違いは、コールバックがコールバックを登録する従来の方法であり、プロミスを返さないの.then()に対して、コールはプロミス(コールバックから返された値で解決される)を.success()返すことです。

Promiseベースのコールバック(.then())を使用すると、Promiseを簡単にチェーンできます(呼び出しを行って結果を解釈してから別の呼び出しを実行し、結果を解釈し、さらに別の呼び出しを行うなど)。

この.success()メソッドは、呼び出しをチェーンしたり、promise APIを操作したりする必要がない場合(たとえば、ルーティングなど)に効率化された便利なメソッドです。

要するに:

  • .then() -promise APIの全機能ですが、もう少し詳細です
  • .success() -promiseを返しませんが、より便利な構文を提供します

44
もう一つの大きな違いがあるということthenながら-応答-コールバックは、単一の引数を取るsuccesserrorarguments--として応答の個々のコンポーネントを取るdatastatusheader、とconfig
ミシェルティリー2013

1
@BrandonTilleyは完全に正しいですが、質問の作成者はすでにそれを理解しているので、ここで繰り返す必要があるとは思いませんでした。
pkozlowski.opensource 2013

45
ドキュメントでは明示的には述べていませんが.success()、チェーン$http(...).success(...).error(...)が可能であるため、メソッドが元の$ http promiseオブジェクトを返すと推測できます。合理的であると思われる場合は、逆$http(...).error(...).success(...)も可能である場合.error()、元のpromiseオブジェクトも返す必要があります。の際立った違い .then()は、それが新しい約束を返すということです。
ビートルートビートルート2013

2
$ httpサービスのangular.jsからのソースコード: promise.success = function(fn) { promise.then(function(response) { fn(response.data, response.status, response.headers, config); }); return promise; };
Alex Che

6
success廃止されることに注意してください。docs.angularjs.org/api/ng/service/$http#deprecation-notice からThe $http legacy promise methods success and error have been deprecated. Use the standard then method instead. If $httpProvider.useLegacyPromiseExtensions is set to false then these methods will throw $http/legacy error.
Sam Barnum

204

ここにはすでにいくつかの良い答えがあります。しかし、提供されている並列処理の違いを理解することは価値があります。

  • success() 元の約束を返します
  • then() 新しい約束を返します

違いはthen()、各呼び出しが新しいプロミスを返すため、シーケンシャルオペレーションを推進することです。

$http.get(/*...*/).
  then(function seqFunc1(response){/*...*/}).
  then(function seqFunc2(response){/*...*/})
  1. $http.get()
  2. seqFunc1()
  3. seqFunc2()

success() ハンドラーは同じpromiseにチェーンされているため、並列処理を駆動します。

$http(/*...*/).
  success(function parFunc1(data){/*...*/}).
  success(function parFunc2(data){/*...*/})
  1. $http.get()
  2. parFunc1()parFunc2()並行して

3
a thenに達したときに返される新しいpromise応答により、successおよびerrorメソッドが表示されなくなることに注意してください。また、HTTPエラー応答(例えば404)のために最初のthen内はhttp.then(ok, err).then(ok, err)に渡すerrハンドラが、以下のものが中を通過しますokハンドラ。基本的http.success().error().success().error()にチェーン可能ですが、$ qプロミスは、具体的にはプロミスと処理のシーケンスに関するものであり(httpリクエストの処理ではありません)、まったく異なります。よく見るまで、理解に苦労しました。
jimmont 2014

1
@jimmont successerror約束の通常のAPIはありませんが、彼らは)($ HTTPの戻り値にボルトで固定されています。
event_jr 2014

@event_jrに感謝します。これは私には明らかで、ドキュメントで呼び出されます。(私にとって)それほど明確ではなかったのは、$ qと$ httpが異なる問題をどのように解決するか、また新しいpromiseを返すか、同じものを通過させるかです(あなたの(非常に役立つ)回答で指摘されています)。
ジムモント2014

1
JSはシングルスレッドなので、パラレルとはどういう意味ですか?実行順序が非決定的であることを意味しますか?
Derek

2
@Derek 2番目successは、最初の1つが実行された後、それから返されるプロミスが解決される前に実行されますが、2番目thenは待機します。promiseを返さない場合、どちらも同じように動作します。
タムリン

114

単純なGETリクエストのいくつかのコード例。多分これは違いを理解するのに役立ちます。使用then

$http.get('/someURL').then(function(response) {
    var data = response.data,
        status = response.status,
        header = response.header,
        config = response.config;
    // success handler
}, function(response) {
    var data = response.data,
        status = response.status,
        header = response.header,
        config = response.config;
    // error handler
});

success/ を使用するerror

$http.get('/someURL').success(function(data, status, header, config) {
    // success handler
}).error(function(data, status, header, config) {
    // error handler
});

5
ありがとうございましたが、問題は、これらの関数の機能の違い、または同じ機能を実行する場合に両方が存在する理由についてです。それらの使い方の違いはドキュメントから理解できます。
ejoubaud 2013年

39
私は個人的に短いコード例が好きで、それをここに投稿しました。Angularのドキュメントは、短い正確な例を見逃していることがあります。
TheHippo 2013年

2
最初の要旨の応答オブジェクトに2番目の要旨の「データ、ステータス、ヘッド、構成」が含まれているという事実を強調することが重要です。つまり、応答オブジェクトには1レベルの深さがあります。
geoom 2014年

data,status,header,config単純に返すよりも、応答値を変数に渡すことの利点はありますresponseか?
ᴍᴀᴛᴛʙᴀᴋᴇʀ

27

.then()はチェーン可能で、以前の.then()が解決するのを待ちます。

.success()と.error()は連鎖させることができますが、それらはすべて同時に起動されます(そのため、それほどポイントはありません)。

.success()と.error()は、簡単な呼び出しに適しています(簡単なメーカー):

$http.post('/getUser').success(function(user){ 
   ... 
})

これを入力する必要はありません:

$http.post('getUser').then(function(response){
  var user = response.data;
})

しかし、一般的に私は.catch()ですべてのエラーを処理します:

$http.get(...)
    .then(function(response){ 
      // successHandler
      // do some stuff
      return $http.get('/somethingelse') // get more data
    })
    .then(anotherSuccessHandler)
    .catch(errorHandler)

IE8以下をサポートする必要がある場合は、.catch()と.finally()を次のように記述します(IEで予約されているメソッド)。

    .then(successHandler)
    ['catch'](errorHandler)

実例:

ここでは、エラー処理などですべてがどのように機能するかについてメモリを更新するために、よりコード化された形式で書いたものを示します。

http://jsfiddle.net/nalberg/v95tekz2/


「return-another-promise」がどのように機能するかを示す唯一の答え
zjk

17

完了のために、違いを示すコード例を次に示します。

成功\エラー:

$http.get('/someURL')
.success(function(data, status, header, config) {
    // success handler
})
.error(function(data, status, header, config) {
    // error handler
});

次に:

$http.get('/someURL')
.then(function(response) {
    // success handler
}, function(response) {
    // error handler
})
.then(function(response) {
    // success handler
}, function(response) {
    // error handler
})
.then(function(response) {
    // success handler
}, function(response) {
    // error handler
}).

すばらしい!、連結が役立つ例はありますか?
geoom 2014年

4
非同期操作を次々と簡単に記述できるため、「その後」のアプローチの方が便利です。
MichaelLo 2014年

2

公式通知:成功とエラーは廃止されました。代わりに標準のthenメソッドを使用してください。

非推奨通知:$ httpレガシーpromiseメソッドの成功とエラーは非推奨になりました。代わりに標準のthenメソッドを使用してください。$ httpProvider.useLegacyPromiseExtensionsがfalseに設定されている場合、これらのメソッドは$ http / legacyエラーをスローします。

リンク:https://code.angularjs.org/1.5.7/docs/api/ng/service/$http

スクリーンショット:スクリーンショットを表示

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.