2012-03-15 74 views
2

我已經做了一些函數來使用Github API檢索數據。我有回調來獲取數據,但我確定如何理解函數退出的位置以及何時停止修改數據。試圖通過填寫對象來了解函數和回調範圍

例如,在下面的代碼中,在第一個函數中,當AJAX調用成功時,回調在第二個函數中被執行,其中數據被操縱。這是否意味着第一個函數的返回是不需要或使用的?在第二個函數中,數據被使用並推送到數組,然後數組返回,或者返回(空)數組返回的位置,然後回調完成它的工作。

我最終試圖從回調中獲取數據到對象中,並從父函數返回填充對象。

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的成功/錯誤之前返回。

所以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您傳遞將在$就關閉範圍存在的回調函數,並將服務器響應的成功執行

下面
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

也可以使這是高度不建議

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調用你的代碼將工作

+0

你能指出一些正確的事情做的例子,我可以嘗試解決這個問題嗎? – Hyposaurus 2012-03-16 01:42:31

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 
        }); 

使用$。當().then()調用ajax並更好地管理回調。 .When