web-dev-qa-db-ja.com

AngularJSでqを使用する複数のチェーン遅延関数がデータを返さない

次の呼び出しが前のdeferred.resolveの結果を取得するように、複数の遅延関数呼び出しを連結しようとしています。これらの呼び出しを2つ以上つなげると、データが返されなくなります。

angularコントローラ内の基本的なコードは次のとおりです。

    $scope.runAsync = function() {
        var asyncFn1 = function(data){
            var deferred = $q.defer();

            $timeout(function(){
                console.log("Async fn1 " + data);
                $scope.outputLines.Push("Async fn1 " + data);
                deferred.resolve("Async fn1 " + data);
            },1000);

            return deferred.promise;
        }

        var asyncFn2 = function(data){
            var deferred = $q.defer();

            $timeout(function(){
                console.log("Async fn2 " + data);
                $scope.outputLines.Push("Async fn2 " + data);
                deferred.resolve("Async fn2 " + data);
            },1000);

            return deferred.promise;
        }

        asyncFn1(1)
        .then(function(data){asyncFn2(data)})
        .then(function(data){asyncFn2(data)})
        .then(function(data){asyncFn2(data)});
    }

これを実行すると、次の出力が得られます。

Async fn1 1
Async fn2 Async fn1 1
Async fn2 undefined
Async fn2 undefined

3番目の呼び出しが2番目の呼び出しから結果を取得し、4番目の呼び出しが3番目の呼び出しから結果を取得するように、それらを連鎖させるにはどうすればよいですか?

JsFiddleを作成しました: http://jsfiddle.net/rhDyL/

32
BoxerBucks

$ qの公式ドキュメントからの抜粋:

then(successCallback、errorCallback)–プロミスが解決または拒否される時期に関係なく、結果が利用可能になるとすぐに非同期で成功コールバックまたはエラーコールバックのいずれかを呼び出します。コールバックは、結果または拒否理由という単一の引数で呼び出されます。

このメソッドは、successCallbackまたはerrorCallbackの戻り値を介して解決または拒否された新しいプロミスを返します。

そして、成功コールバックまたはエラーコールバックの戻り値については、 ドメニックのスライド

戻り値がプロミスである場合、プロミスは返されたプロミスの状態を採用します。そうでない場合、成功コールバックはすぐに戻り値で呼び出されます

定義に基づいて、コードにはreturnキーワードがありません。次のようになります。

    asyncFn1(1)
    .then(function(data){return asyncFn2(data)})
    .then(function(data){return asyncFn2(data)})
    .then(function(data){return asyncFn2(data)});
40
tamakisquare