web-dev-qa-db-ja.com

チェーンAngular $ httpは適切に呼び出しますか?

私は何日もの間$ qと約束について読んでいて、それを理解しているようです...いくらか。実際には次のような状況にあります。

  1. $ http要求が行われ、後続の呼び出しが可能かどうかがチェックされます。
  2. 最初の呼び出しが失敗した場合、「データなし」を返します。成功し、呼び出しが可能であれば、2番目の呼び出しが行われます。 2番目の呼び出しが成功した場合、データを返します。そうでない場合、「データなし」。これは次のようになります(おおよそ、一般的な考え方のために簡略化していますので、ここでの小さな間違いについては心配しないでください):

            return $http.get (something)
                .then(function(allowedAccess){
                    if(allowedAccess){
                        return $http.get (somethingElse)
                            .then( function(result){return {data:result} },
                            function(error){return {data:"n0pe"} }
                        )
                    } else {
                        return {data:"n0pe"}
                    }
                },
                function(){ return {data:"n0pe"} });
    

ここで$ qを使用するように言われました。どうして、どうしてそうなるのか、私にはよくわかりません。 $ http呼び出しは既に約束されています。

このクリーナーを作る方法がある場合、私はそれを見ません。これを読み直しました 件名に投稿 。本質的に、私は何かを見逃していますか/これを行うより良い方法はありますか?

編集:また、読み直してください Promiseのチェーンに関するチュートリアル -呼び出しの失敗をまったく処理しません。基本的にこれをデューデリジェンスとして投稿します。

編集2:これは、最初の記事からの抜粋であり、私が尋ねている理論の詳細です。

ただし、これは簡単な例です。 then()コールバックが別のプロミスを返すと、本当に強力になります。その場合、次のthen()は、promiseが解決した後にのみ実行されます。このパターンは、たとえば、シリアルHTTPリクエストに使用できます(リクエストは以前のリクエストの結果に依存します)。

これは次のようなチェーンについて話しているようです:

   asyncFn1(1)
    .then(function(data){return asyncFn2(data)})
    .then(function(data){return asyncFn3(data)})

だから、私がこれを正しく理解していれば、a)。 3番目の機能がないため、私には当てはまりません。 b)。最初の$ httpリクエスト内でifステートメントを実行しているときに、ifステートメント内でのみ別のプロミスを返すため、3つの関数があれば適用されます。したがって、理論的には、チェーンする非同期関数が3つある場合、ifステートメントをpromise内に配置する必要がありますか?

17
VSO

約束は、非同期呼び出しを行うコード構成で本当に役立ちます。言い換えると、同期呼び出しセットを構成する方法(チェーン.thensを使用)と同様の方法で、同期コードがtry /にあるかのようにコードを構成できます。 catchブロック(.catchを使用)。

したがって、HTTP呼び出しがブロックされていることを想像してください-ロジックは次のようになります。

var allowedAccess, data;
try {
  allowedAccess = $http.get(something);

  if (allowedAccess){
    try{
      var result = $http.get(somethingElse);
      data = {data: result};
    } catch (){
      data = {data: "n0pe"};
    }
  } else {
    data = {data: "n0pe"};
  }
} catch (){
  data = {data: "n0pe"};
}
return data;

あなたはそれを少し単純化することができます:

var allowedAccess, result;
try {
  allowedAccess = $http.get(something);
  var result;
  if (allowedAccess) {
     result = $http.get(somethingElse);
  } else {
     throw;
  }
  data = {data: result};
} catch () {
   data = {data: "n0pe"};
}
return data;

そして、それは非同期バージョンに変換されます:

return $http
          .get(something)
          .then(function(allowedAccess){
             if (allowedAccess){
               return $http.get(somethingElse);
             } else {
               return $q.reject(); // this is the "throw;" from above
             }
          })
          .then(function(result){
             return {data: result};
          })
          .catch(function(){
             return {data: "n0pe"};
          })

少なくとも、これは分岐と非同期呼び出しでコードを作成するときに適用できる理由です。

私が提示したバージョンが最適または短いと言っているわけではありません-それはis、しかし、より多くのDRY単一エラー処理。ただし、.then(success, error)を実行すると、以前の非同期操作のtry/catchと同等であることに注意してください。これは、特定の状況に応じて必要な場合と必要ない場合があります。

13
New Dev

これは私がこの種の問題をコーディングする方法です:

// returns a promise that resolves some endpoint if allowed
function getDataWithAccess(allowed){
    return allowed ? $http.get(someEndpoint) : $q.reject();
}

// do something with data
function handleData(data){
    // do stuff with your data
}

// main chain
$http.get(accessCredEndpoint)
    .then(getDataWithAccess)
    .then(handleData)
    .catch(function(err){
        return { data: "n0pe" };
    });

はい、これはNew Devの答えに非常によく似ていますが、関数を独自のブロックに抽出することを強調したかったのです。これにより、コード全体がはるかに読みやすくなります。

7
Matt Way