40

jQuery deferreds を使用すると、次のように現在の状態を確認できるようになりました。

var defer = $.Deferred();
defer.state();  //Returns the state of the deferred, eg 'resolved'

Angular deferred に対して同じことを行う方法はありますか? (またはさらに良い約束)

4

4 に答える 4

85

更新

$q のリファクタリングにより、文書化されていませんが、これが可能になりました:

promise.$$state.status === 0 // pending
promise.$$state.status === 1 // resolved
promise.$$state.status === 2 // rejected

オリジナル:

ほとんどの promise ライブラリ (Bluebird、Q、when、RSVP など) とは異なり、$q は同期検査 API を公開しません。

外部からこれを達成する方法はありません。

promiseを呼び出す必要が.thenあり、promise が満たされたときにそのハンドラのコードが実行されます。

于 2014-06-06T23:16:25.530 に答える
34

あなたの質問への答えは次のとおりです。はい、方法があります。他の回答は、の組み込みの制限をうまくカバーしてい$qます。ただし、サービスのデコレータ関数$qを使用して状態プロパティを追加するのは簡単です。$provide

  $provide.decorator('$q', function ($delegate) {
    var defer = $delegate.defer;
    $delegate.defer = function() {
      var deferred = defer();

      deferred.promise.state = deferred.state = 'pending';

      deferred.promise.then(function() {
        deferred.promise.state = deferred.state = 'fulfilled';
      }, function () {
        deferred.promise.state = deferred.state = 'rejected';
      }); 

      return deferred;
    };
    return $delegate;
  });

このデコレーターをconfigブロック内に配置すると、インスタンス化されたすべてのdeferredおよびpromiseオブジェクトはpending$qfluided 、またはrejectを持つプロパティを持ちます。state

このプランクをチェックしてください


懐疑的?

$q 自体を効果的に変更し、すべての deferred を別の deferred でラップしています

実際にはそうではありません。$qの元のdefer()コンストラクターは 1 回だけ呼び出されます。を介してイベント ハンドラーを内部的にアタッチすることにより、追加機能で単純に装飾されthenます。[各遅延オブジェクトで自動的に作成される追加のコールバックdeferの結果として、追加のオブジェクトがインスタンス化されることに注意してください...これは、角度が内部でどのように機能するかであるため、予想されます。]then

promise は deferred で作成されるべきではなく、API から返された promise からチェーンされているため、これは機能しません。

このコードは、サービスによって作成されたすべての遅延 (およびpromiseオブジェクト) をデコレートすることに注意してください。$qこれは、$q を利用するすべての API が自動的にstateプロパティで装飾されることを意味します。をどのように使用する$qかに関係なく、何らかの API を使用するか単独で使用するかに関係なく、このソリューションはdeferredオブジェクトと の両方をデコレートします。それを証明するためにplunkpromiseを提供しました。


生産に値する?

このアプローチは単体テスト可能であり、既に を使用しているアプリケーションを壊さない$qことが保証されており、古いデコレーターを変更せずに後で追加のデコレーターを追加できるという意味で柔軟性があります。$q

于 2014-06-07T08:00:06.747 に答える