2017-08-16 9 views
1

私は実際にanglejsサービスである私のコードと混同しています。 Promise.allを使用して、サービスの一部である2つの約束事を連結し、その結果を私のコントローラに送信しようとしました。 Promise.allによって返されたオブジェクトは、2つの同じ配列で構成されています。 ここで私のコード、単に明確にすべき:Promise.allの2番目の引数が正確AときPromise.all()は予期しない値を返す

batchModule.service('BatchService', ['$http', '$q', '$log', 'MessageboxService', function ($http, $q, $log, MessageboxService) { 

let deferred = $q.defer(); 

this.loadAll =() => { 

    promise1 =() => { 
     $http.get(_restApiPath + "/batch/?processtype=IMPORT_CUSTOMER") 
     // loadLastFiveBatch('IMPORT_CUSTOMER') 
      .then(function (response) { 
       deferred.resolve(response.data); 
       // datas.push(response1); 
       // console.log(datas); 
      }, function (error) { 
       deferred.reject(error); 
       $log.error(error); 
      }); 
     return deferred.promise; 
    }; 

    promise2 =() => { 
     $http.get(_restApiPath + "/batch/?processtype=IMPORT_LAB_MARGIN") 
     // loadLastFiveBatch('IMPORT_LAB_MARGIN') 
      .then(function (response) { 
       deferred.resolve(response.data); 
       // datas.push(response2); 
       // console.log(datas); 
      }, function (error) { 
       deferred.reject(error); 
       $log.error(error); 
      }); 
     return deferred.promise; 
    }; 

    Promise.all([promise1(), promise2()]) 
    .then(values => { 
     console.log(values); 
    }); 

}; 
}]); 

にconsole.log(値)は、IMPORT_CUSTOMER要求によって返さ2つの等しい配列からなるオブジェクトを返しますIMPORT_MARGIN要求によって返される約束。 今日は数時間で作業していましたが、解決策が見つかりません。 私は十分にはっきりしていたと思う、私の英語はあまり良くない。 あなたのお返事ありがとうございます:-)

+2

を使用するchainging考えてみましょう、それだけで1つの値に解決することができますなぜそれがちょっと明らかです。そして、もちろん、最初の段階で[反遅延アンチパターン](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)を避けてください場所! – Bergi

答えて

1

問題が生じました。その参照が解決されるように、それはあなたの約束の呼び出しのさらなるインスタンスのために解決されます。そのため、リクエストごとに異なる遅延を使用してください。まだ私はdeferred anti-patternを使用することをお勧めしません。むしろ、$http.getメソッドによる約束のもとでビルドを使用してください。

また、関数の最後にPromise.allがありましたが、これは角度ダイジェストサイクルを実行しません。結局、この関数からバインディングを更新しようとしても、UIのバインディングは更新されません。それはあなたが唯一の単一のグローバル `deferred`を持って$q.all

this.loadAll =() => { 

    promise1 =() => { 
     return $http.get(_restApiPath + "/batch/?processtype=IMPORT_CUSTOMER") 
      .then(function (response) { 
       return response.data; 
      }, function (error) { 
       $log.error(error); 
       return $q.reject(error); 
      } 
     ); 
    }; 

    promise2 =() => { 
     $http.get(_restApiPath + "/batch/?processtype=IMPORT_LAB_MARGIN") 
     // loadLastFiveBatch('IMPORT_LAB_MARGIN') 
      .then(function (response) { 
       return response.data; 
      }, function (error) { 
       $log.error(error); 
       return $q.reject(error); 
      } 
     ); 
    }; 
    //return is needed if any function is trying to chain `loadAll` function. 
    return $q.all([promise1(), promise2()]) 
    .then(values => { 
     console.log("promise1", values[0]); 
     console.log("promise2", values[1]); 
    }); 

}; 
1

約束は実際には同じ$q.defer();約束を返します。だから、延期されたアンチパターン(return $http.get(..);の代わりに$q.defer()を使用)を落とす必要があります。問題はかなり解決するはずです。

だからこれにコードを変更:あなたの約束のすべてのために延期単独で使用するので

batchModule.service('BatchService', ['$http', '$q', '$log', 'MessageboxService', function ($http, $q, $log, MessageboxService) { 

    this.loadAll =() => { 

     promise1 =() => { 
      return $http.get(_restApiPath + "/batch/?processtype=IMPORT_CUSTOMER") 
       .then(response => response.data, error => { 
        $log.error(error); 
        return $q.reject(error); 
       }); 
     }; 

     promise2 =() => { 
      return $http.get(_restApiPath + "/batch/?processtype=IMPORT_MARGIN") 
       .then(response => response.data, error => { 
        $log.error(error); 
        return $q.reject(error); 
       }); 
     }; 

     $q.all([promise1, promise2]) 
     .then(values => { 
      console.log(values); 
     }); 
    }; 
}]); 
+0

ありがとうNikolaj。 –

+0

'Promise.all'はAngularJSフレームワークとそのダイジェストサイクルと統合されていないことに注意してください。問題を回避するには、代わりに[$ q.all](https://docs.angularjs.org/api/ng/service/$q#all)を使用します。** AngularJSは、独自のイベントを提供することによって通常のJavaScriptフローを変更します処理ループ。これにより、JavaScriptが古典的なAngularJS実行コンテキストに分割されます。 AngularJSの実行コンテキストで適用される操作のみが、AngularJSのデータバインディング、例外処理、プロパティの監視などの恩恵を受けます。 – georgeawg

+0

'Promise.all'を' $ q.all'に変更しました。その部分を盲目的にコピー貼り付けただけです。 :-) –

関連する問題