2016-04-04 18 views
1

別の配列に基づいて構築された約束事を解決してオブジェクトの配列を構築する必要があります。Ajaxコールの配列を構築するときにJQuery Ajax成功コールバックが機能しない

私はletters = ['a', 'b', 'c']の配列を持っているとしましょう。その後、私はこのように、それはAjaxがPARAMとして各文字を使用して呼び出して作るマップ:結果

var result = letters.map(function (letter) { 
 
    return $.getJSON('myuri', { param: letter }); 
 
};

、私はアヤックスの約束を持つ配列を取得します。それから私はこのようにそれを解決:

Promise.all(result).then(function (response) { 
 
    console.log(response); 
 
});

ログはすべてのAJAX呼び出しのために元の応答を印刷しています。それまではすべてがうまくいきます。

var letters = ['a', 'b', 'c']; 
 

 
var result = letters.map(function (letter) { 
 
    return $.getJSON('myuri', { param: letter }) 
 
      // Chaining with success callback 
 
      .done(function (response) { 
 
       return { 
 
        'custom_attr': response.x, 
 
        'athor_custom_attr': response.y 
 
       }; 
 
    }); 
 
}); 
 

 
Promise.all(result).then(function (response) { 
 
    console.log(response); 
 
});

問題は成功コールバックです:しかし、私はこのように、私はそれらを作成するためのAjaxの成功コールバックを使用してみましたので、私は、カスタムオブジェクトをしたい、オリジナルの応答をしたくありませんアレイ作成時に干渉しません。実際には、コールバックの何かへのリターンを変更することはできますが、それは何の違いもなく、コードは元の応答の配列を返します。

$httpサービスを使用してAngularでこれを実行したとき、それは正常に機能しましたが、$.getJSONを使用するJQueryでは機​​能しません。なぜこれが起こっているのか理解できません。

ありがとうございます。

+0

'map'関数では、各文字を[jqXHR](http://api.jquery.com/Types/#jqXHR)オブジェクトにマッピングします。 Promiseが解決されたら、 'result'配列をもう一度繰り返し、各jqXHRのレスポンスデータを必要なカスタムオブジェクトにマップする必要があります。 – romellem

+0

しかしそれはPromise.allがしなければならないことです。これは、すべての約束を非同期的にトリガーし、それぞれの対応する結果で配列を構築します。 –

+0

[Promise.all(iterable)メソッドは、iterable引数のすべての約束が解決されたときに解決する約束を返します。または、拒否する最初に渡された約束の理由で拒否します。](https://developer.mozilla。 org/ja-jp/docs/Web/JavaScript/Reference/Global_Objects/Promise/all)を参照してください。だから '$ .getJSON'は約束を返します。だから 'result'はPromisesの配列です。 「Promise.all(結果)」は、「すべての約束を約束する」と言っているので、「これらすべての約束が終わったら、この成功の機能を実行する」と言います。この関数では、カスタムオブジェクトを作成する場所です。 – romellem

答えて

1

あなたのコールバックdoneを使用したため、戻り値は無視されます。

var result = letters.map(function (letter) { 
    return $.getJSON('myuri', { param: letter }) 
     .then(function (response) { 
      return { 
       'custom_attr': response.x, 
       'athor_custom_attr': response.y 
      }; 
     }); 
}); 

done方法が連鎖可能なされていない:あなたが実際に望んでいたことは、コールバックの結果のための新たな約束を作成するthenを使用することです!then以上に使用する理由はほとんどありません。

+0

それは働いた!私は以前に「then」を使用しましたが、結果は同じでした。しかし、今私は単に働いた。ありがとう。 –

+0

興味深いことに、 'done'は連鎖できませんでした。おかげでき! – romellem

+0

@romellem:技術的には、呼び出された約束を返すので、技術的にはもっと多くのメソッド呼び出しをチェーンすることができますが、モナドの意味ではチェーン化できません。 – Bergi

1

私のコメントで述べたように、各jqXHRの応答データを必要なカスタムオブジェクトにマップするだけでよいと思います。

だから、のようなもの:

Promise.all(result).then(function (response) { 
    result = response.map(function(c) { 
     return { 
      'custom_attr': c.x, 
      'another_custom_attr': c.y 
     }; 
    }); 
}); 

これはvar result;はここにアクセス可能になる範囲内で宣言されたと仮定しています。

[ 
    {custom_attr: "a"}, 
    {custom_attr: "b"}, 
  {custom_attr: "c"} 
] 
:だから、一日の終わりに、 resultがに等しい

<?php 
// json.php 
header('Pragma: no-cache'); 
header('Cache-Control: no-store, no-cache, max-age=0, must-revalidate'); 
header('Content-Type: application/json'); 

echo json_encode($_GET); 
?> 

<!-- index.html --> 
<button class="load-ajax">Click To Make our AJAX calls!</button> 
<script src="jquery.min.js"></script> 

<script> 
// Declare `result` in global scope. 
var result; 

$(document).ready(function() { 
    $('.load-ajax').on('click', function(e) { 
     e.preventDefault(); 

     var letters = ['a', 'b', 'c']; 
     result = letters.map(function (letter) { 
      return $.getJSON('json.php', { param: letter }); 
     }); 

     Promise.all(result).then(function (response) { 
      result = response.map(function(c) { 
       return { "custom_attr" : c.param }; 
      }); 
      console.log("DONE! Look at `result`"); 
     }); 
    }); 
}); 
</script> 

およびサンプルjson.phpファイル:


はここで完全なサンプルです

+0

私はあなたのコードを試して、再度iterating問題を解決しました。しかし、特にAngularではそれを行う必要がなかったので、JQueryを使って私がなぜそう思っていたのか、もう一度やり直す必要はありません。ありがとうございました! –

関連する問題