2012-03-15 27 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