2012-03-15 4 views
2

Github APIを使用してデータを取得する関数をいくつか作成しました。私はデータを取得するためにコールバックを用意していますが、関数がどこで終了し、いつ変更を止めるのかを理解する方法はわかります。オブジェクトを記入して関数とコールバックのスコープを理解しようとしています

たとえば、最初の関数では、AJAX呼び出しが成功すると、データが操作される2番目の関数でコールバックが実行されます。これは、最初の関数の戻り値が必要ない、または使用されていないことを意味しますか? 2番目の関数では、データが使用され、配列にプッシュされた後、配列が返されます。または、逆に(空の)配列が返され、コールバックがその処理を行います。

私は最終的にコールバックからオブジェクトにデータを取得し、その埋め込まれたオブジェクトを親関数から戻そうとしています。ここで

function makeAJAXCall(hash, cb) { 
    var returnedJSON, cb = cb, hash = hash; 
    $.ajax({ 
     accepts: 'application/vnd.github-blob.raw', 
     dataType: 'jsonp', 
     url: hash, 
     success: function (json) { 
      console.info(json); 
      returnedJSON = 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; 
     } 
    }); 
    return returnedJSON; 
} 

function parseBlob(hash) { 
    var objectedJSON, objectList = [], i; 
    objectedJSON = makeAJAXCall(hash, function (objectedJSON) { // no loop as only one entry 
     objectList.push(objectedJSON.content); 
    }); 
    return objectList; 
} 

function walkTree(hash) { 
    var objectedJSON, objectList = [], i, entry; 
    var hash = 'https://api.github.com/repos/myAccountName/repo/git/trees/' + hash; 
    objectedJSON = makeAJAXCall(hash, function (objectedJSON) { 
     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)); 
      } 
     } 

    }); 
    console.info(objectList); 
    return objectList; 
} 

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

答えて

2

あなたはAJAXコールAを作っているあなたの成功/エラーコールバックが非同期で実行されます。すなわち、非同期を指します。

makeAJAXCallは、$ ajaxの成功/エラーを実行する前に戻ります。あなたは$アヤックスの閉鎖範囲に存在しています渡しているmakeAjaxCallコールバック関数を呼び出し、サーバの応答の成功に実行されるとき

のでobjectedJSON = makeAJAXCallは今あなたにundefined

function makeAJAXCall(hash, cb) { 
    $.ajax({ 
     accepts: 'application/vnd.github-blob.raw', 
     dataType: 'jsonp', 
     url: hash, 
     success: function (json) { 
      // this function will be executed after getting response from server 
      //ie Asynchronously 
      //here cb passed from the makeAjaxCall exist in the closure scope 
      if (cb) { 
       cb(json); 
      } 
     }, 
     error: function (error) { 
      console.error(error); 
      // an error happened, check it out. 
      throw error; 
     } 
    }); 
} 

を返します

makeAJAXCall(hash, function (objectedJSON) { 
    //objectJSON contains the response from server 
    // do all your operations using server response over here or assign it to a global variable 
}); 

チェックは以下

https://developer.mozilla.org/en/JavaScript/Guide/Closures

リンク

https://mikewest.org/2009/05/asynchronous-execution-javascript-and-you

かは非常にあなたのコードが

+0

私はこれを修正しようとする可能性がある正しいことが行われているいくつかの例を指摘できますか? – Hyposaurus

1
function makeAJAXCall(hash, cb) { 
    var returnedJSON, cb = cb, hash = hash; 
    return $.ajax({ 
     accepts: 'application/vnd.github-blob.raw', 
     dataType: 'jsonp', 
     url: hash, 
     success: function (json) { 
      console.info(json); 
      returnedJSON = 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) { 
    var objectedJSON, objectList = [], i; 
    objectedJSON = makeAJAXCall(hash, function (objectedJSON) { // no loop as only one entry 
     objectList.push(objectedJSON.content); 
    }); 
    return objectList; 
} 

function walkTree(hash) { 
    var objectedJSON, objectList = [], i, entry; 
    var hash = 'https://api.github.com/repos/myAccountName/repo/git/trees/' + hash; 
    objectedJSON = $.when(maxAJAXCall) 
        .then(function(){ 
          //Write the callback 
        }); 

使用$ .whenに動作します上記のケースで

function makeAJAXCall(hash, cb) { 
    var returnedJSON; 
    $.ajax({ 
     accepts: 'application/vnd.github-blob.raw', 
     dataType: 'json', 
     async : false, //this will make it in sync 
     url: hash, 
     success: function (json) { 
      console.info(json); 
      returnedJSON = json; 
     //now makeAJAXCall will wait for success to complete and it will return only after executing success/error 
     // Time for callback to be executed 
      if (cb) { 
       cb(json); 
      } 
     }, 
     error: function (error) { 
      console.error(error); 
      // an error happened, check it out. 
      throw error; 
     } 
    }); 
    //will wait for success/error before returning 
    return returnedJSON; 
} 

をお勧めしませんasync:falseを使用して同期して、あなたのAJAX呼び出しを行うことができます().then()を呼び出してajaxを呼び出し、コールバックをよりうまく管理します。 .When

関連する問題