Angular.jsで約束が果たされたときに常にコードを実行する方法


83

私のAngular.jsアプリケーションでは、非同期操作を実行しています。開始する前に、モーダルdivでアプリケーションをカバーします。操作が完了したら、操作が成功したかどうかに関係なく、divを削除する必要があります。

現在私はこれを持っています:

LoadingOverlay.start(); 
Auth.initialize().then(function() {
    LoadingOverlay.stop();
}, function() {
    LoadingOverlay.stop(); // Code needs to be duplicated here
})

それはうまく機能しますが、私はこの疑似コードのようなよりクリーンなものが欲しいです:

LoadingOverlay.start(); 
Auth.initialize().finally(function() { // *pseudo-code* - some function that is always executed on both failure and success.
    LoadingOverlay.stop();
})

これはかなり一般的な問題だと思うので、できると思っていましたが、ドキュメントに何も見つかりませんでした。それができるかどうか何か考えはありますか?


あなたがチェーン1ができればthen()、あなたは別のをチェーン確実にすることができます... .initialize().then(...).then(...)。そのような「最終的な」ものはありません。最後のハンドラーは、最後に指定されたハンドラーです。
ビートルート-ビートルート2013

2
@ Beetroot-ビートルート。initialize()失敗した場合でも、「成功」関数と「失敗」関数の両方を宣言し、そこにコードを複製する必要があるため、機能しません。
laurent 2013

動作しませんか、それとも単にエレガントではありませんか?
ビートルート-ビートルート2013

1
Laurent、あなたが望むものは現在Angularの軽量$ qサービスでは利用できません。このサービスは、たった1つのメソッドで.then()Promiseを提供しますここの「ThePromiseAPI」を参照してください。唯一の自由は、1つを持つ.then()か、複数.then()のをチェーンすることです。より広範なpromiseAPIを希望するのはあなたが最初ではありません。必要な機能はここで正式にリクエストされます
ビートルート-ビートルート2013

1
どうやらalways(callback)実装されていないか、角度1.2.6でロールバックされていません。私たちはfinally今使わなければなりません。なぜ予約語finallyalways。よりも優れているのだろうか。
Aleyna 2013

回答:


164

この機能はこのプルリクエストに実装されており、AngularJSの一部になっています。最初は「always」と呼ばれ、その後名前がに変更されたfinallyため、コードは次のようになります。

LoadingOverlay.start(); 
Auth.initialize().then(function() {
    // Success handler
}, function() {
    // Error handler
}).finally(function() {
    // Always execute this on both error and success
});

finallyは予約済みのキーワードであるため、特定のブラウザ(IEやAndroidブラウザなど)で壊れないように文字列にする必要がある場合があることに注意してください。

$http.get('/foo')['finally'](doSomething);

10
Web検索からこれを見つけた人は、回答のリンクが関数を参照していましたが、このコミット(またはソース)で確認できるalwaysように変更さfinallyれました:github.com/angular/angular.js/commit/…
オースティントンプソン

@AustinThompson、情報をありがとう、私は投稿を更新しました。
laurent 2014

@ this.lau_finally()はチェーンの最後の呼び出しである必要がありますか、それともそれからさらにthen()をチェーンできますか?
ブライアン

2
あなたは、私の日を作りました!
JacobF 2014年

4
@Brianfinallyは他の約束と同じように約束を返すので、それを連鎖させることができます。ただし(少なくともAngularの一部のバージョンでは)利便性が過負荷にsuccessなりerror、の即時リターンにのみ追加される$httpため、最初から始めると、finallyこれらのメソッドが失われます。
drzaus 2015年

7

Umbracoバージョン7.3.5バックエンドとAngularJSバージョン1.1.5を使用していて、このスレッドを見つけました。承認された回答を実装すると、エラーが発生しました。

xxx(...)。then(...)。finallyは関数ではありません

しかし、うまくいったのはでしたalways。古いバージョンのAngularJSを使用している他の誰かがこのスレッドを見つけて使用できない場合finallyは、代わりにこのコードを使用してください

LoadingOverlay.start(); 
Auth.initialize().then(function() {
    // Success handler
}, function() {
    // Error handler
}).always(function() {
    // Always execute this on both error and success
});

2

angleJSを使用していない場合で、エラーをキャッチしても問題がない場合(.finally()がそれを実行するかどうかはわかりません)、. catch()。then()を使用してコードの重複を回避できます。

Promise.resolve()
  .catch(() => {})
  .then(() => console.log('finally'));

catch()は、とにかくロギングやその他のクリーンアップに役立つ可能性があります。 https://jsfiddle.net/pointzerotwo/k4rb41a7/


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