2012-03-17 14 views
0

だけでなく、下のJavaScriptの「再帰AJAXコールバック」はどのように機能しますか?

Here is the script on jsfiddleを、私は私のレポの1程度のデータを取得するために、GitHubのAPIを使用していると私は、コールバック関数と再帰関数は、(それらに添付のコールバックと再帰関数のように)重複するトラブルに実行しています:

(function() { 
    'use strict'; 

    function makeAJAXCall(hash, cb) { 
     $.ajaxSetup({ 
      accept: 'application/vnd.github.raw', 
      dataType: 'jsonp' 
     }); 

     $.ajax({ 
      url: hash, 
      success: function (json) { 
       //console.info(json); 
       // Time for callback to be executed 
       if (cb) { 
        cb(json); 
       } 
      }, 
      error: function (error) { 
       console.error(error); 
       // an error happened, check it out. 
       throw error; 
      } 
     }); 
    } 

    function parseBlob(hash) { 
     return makeAJAXCall(hash, function (returnedJSON) { // no loop as only one entry 
      console.log(returnedJSON.data); 
      return returnedJSON.data.content; 
     }); 
    } 

    function walkTree(hash) { 
     var tree = 'https://api.github.com/repos/myusername/SVG-Shapes/git/trees/' + hash; 
     return makeAJAXCall(tree, function (objectedJSON) { 
      var objectList = [], i, entry; 
      for (i = 0; i < objectedJSON.data.tree.length; i += 1) { 
       entry = objectedJSON.data.tree[i]; 
       //console.debug(entry); 
       if (entry.type === 'blob') { 
        if (entry.path.slice(-4) === '.svg') {  // we only want the svg images not the ignore file and README etc 
         //console.info(entry.path) 
         objectList.push(parseBlob(entry.url)); 
        } 
       } else if (entry.type === 'tree') { 
        objectList.push(walkTree(entry.sha)); 
       } 
      } 
      if (cb) { 
       console.log(objectList); 
       cb(objectList); 
      } 
      return objectList; 
     }); 
    } 

    $(document).ready(function() { 
     var returnedObjects = walkTree('master', function (objects) {  // master to start at the top and work our way down 
      console.info(objects); 
     }); 
    }); 
}()); 

返されるJSONは、ブログ(ファイル)またはツリー(ディレクトリ)です。それがツリーの場合は、walkTree関数が再度呼び出されます。私はここでコールバックがどのように動作するのか、関数の中から最終ブロックに至るまでデータを取得する方法を理解していません。

誰かがこれをどうやって行うべきかを明確にすることはできますか?

答えて

4

通常、Ajax呼び出しは非同期です。つまり、ajax呼び出しを行うと、ajax呼び出しが開始され、後で終了します。一方、ajax呼び出しの開始後の残りのコードは、完了するまで実行を続けます。

その後、いつかajax呼び出しが終了すると、success関数が呼び出され、あなたの場合は、成功関数によってコールバック関数が呼び出されます。成功関数は、makeAJAXCall()関数がすでに終了した後に、ずっと後で呼び出されることを理解することが重要です。

したがって、関数が返ってくるときはまだわからないので、makeAJAXCall()関数からajaxデータを返すことはできません。

実際には、2つのだけの場所はあなたがAJAX呼び出しの結果を使用することができます:成功ハンドラで

  1. 成功ハンドラを呼び出すいくつかの機能に直接
  2. あなたのケースではそれコールバック関数。

したがって、コールバック関数からはreturn returnedJSON.data.content;にはうってつけです。これは、Ajaxインフラストラクチャの内部に戻って何もしないことです。その戻り値は床に落とされ、失われます。

代わりに、そのコールバック関数にreturnedJSON.data.contentを使用するコードを置く必要があります(または、関数呼び出しで別の関数に渡す必要があります)。

Ajaxは非同期です。つまり、ajaxを使用するときには通常のシーケンシャルプログラミングはできません。代わりに、イベント駆動型プログラミングを行う必要があります。この場合、イベントはajax呼び出しの成功完了時に呼び出されるコールバックです。これらのajax結果を使用するすべての作業は、その成功ハンドラまたはそれから呼び出されるコールバックから開始する必要があります。