16

新しいTypeScript非同期/待機機能はES6の約束を使用します。 AngularJSはわずかに異なるインターフェイスで$qサービス約束を使用します。

$qサービスの約束でTypeScript非同期/待機機能を使用する方法はありますか?

+1

はい。最初の問題は、ng-serviceからのすべての約束応答を、それに対して待機するために使用するように変換する必要があることです。 2番目の問題は、表現が待っていることによって生成されたES6-約束が角度ダイジェストサイクルを開始しないということです。 – Random

答えて

16

はどのように行うのです:

angular.module('your app') 
     .run(['$window', '$q', function($window, $q) { 
      $window.Promise = $q; 
     }]); 
+0

ありがとう、私のバージョンよりはるかにきれいです。私は、$ qサービスがes6-promisesと互換性のあるコンストラクタとして使用できることを知らなかった – Random

+1

これはうまくいきましたが、今私はいくつかのプロジェクトでそれを使用しています。しかし、私は助けることができませんが、これはいたずらであると感じるを振る。グローバルプロミスオブジェクトをAngular $ qサービスに置き換えると、ハッキーです。 –

+2

ネイティブプロミスを$ qに置き換えることはおそらくアプリケーションにとって最悪のことです。これらは基本的に異なる実装です。これは、「約束」に依存するサードパーティのすべてのコードを破壊します。 'hackish' $ windowに関するステートメントはfalseです。Angularはネイティブウィンドウを使用できないので、DIは良好です。 – estus

3

私はあなたがそれらを直接使用することはできないと思います。しかし、このように、++の約束に何かをq個の約束を変換するのは非常に簡単なはず:すべてのファイルどこに__awaiter関数を生成する活字体1.8のため

declare var __awaiter: Function; 
(window as any).__awaiter = __awaiter; // set global __awaiter to avoid declaring default __awaiter in other files 
async() => { } // dummy async function to generate __awaiter code for current file 

angular.module('ts-awaiter', []).run(['$timeout', ($timeout: ng.ITimeoutService) => { 
    function wrap(func: Function) { 
     return function() { 
      func.apply(this, arguments); 
      $timeout(() => { }); // run angular digest 
     }; 
    } 

    var oldAwaiter = __awaiter; 
    (window as any).__awaiter = (thisArg: any, _arguments: any, P: Function, generator: any) => { 
     P = function (executor: Function) { 
      return new Promise<any>((resolve, reject) => { 
       resolve = wrap(resolve); 
       reject = wrap(reject); 
       executor(resolve, reject); 
      }); 
     }; 
     return oldAwaiter(thisArg, _arguments, P, generator); 
    }; 
}]); 

Comliper:

function Convert<T>(qPromise): Promise<T> 
{ 
    return new Promise<T>((resolve, reject) => 
    { 
     qPromise.then((result: T) => resolve(result), (e) => reject(e)); 
    }); 
}; 
+4

問題は、この場合、$ q約束を返す各ngサービスをラップする必要があるということです。また、ES6-promisesは角度ダイジェスト・サイクルを開始しません。だから、この場合、私は 'await'の後に' $ apply'を呼び出さなければなりません。 – Random

1

は最後に、私は次の回避策を使用しましたawait演算子が使用されます。私はresolverejectが呼び出されるたびにダイジェストサイクルを開始するカスタムPromiseコンストラクタを渡す実装に置き換えます。ここで使用例である:ここでhttps://github.com/llRandom/ts-awaiter

+0

好奇心の外に、これはどうやって拒否するのですか?ブロックをキャッチ? – Luis

+0

はい。リポジトリに例を追加 – Random

+0

これは不必要なダイジェストをもたらす可能性があり、ダイジェストはAngularJSアプリのパフォーマンスにとって最も一般的なボトルネックです。このソリューションはTypeScript ES2017ターゲットには適用されません。native async/awaitは既に存在します。 – estus

関連する問題