2011-06-25 109 views
0

我有試圖從以下面的方式呼叫功能捕獲返回值的函數:無法從JavaScript函數返回一個對象的值

var select = xhrRetrieve(projID); 

這裏是xhrRetrieve函數的一個例子:

function xhrRetrieve(projID) { 
    var xhr = new XMLHttpRequest(); 

    xhr.onreadystatechange = function() { 
     if(xhr.readyState == 4) { 
      if(xhr.status == 200) { 
       var obj = $.parseJSON(xhr.responseText); 

       return obj.select.toString(); 
      } 
     } 
    } 

    var url = "ajax.cgi"; 
    var data = "action=retrieve-opp&proj-id=" + projID; 

    xhr.open("POST",url); 
    xhr.setRequestHeader("Content-Type","application/x-www-urlencoded"); 
    xhr.send(data); 

} 

我正在使用jQuery結合直JavaScript。每當我嘗試使用得到obj.select值:

var select = xhrRetrieve(projID); 

選擇總是回來undefined

我在做什麼錯?

回答

1
  1. 該函數不返回任何
  2. 你打電話功能的時刻,(目前不存在)的返回值被分配到select。同時,您的ajax請求正在被解僱,這需要時間來完成;直到ajax請求完成(併成功),纔會調用回調函數。

這應該工作:

function doStuffWithTheAjaxResponse(select) { 
    // do stuff 
} 

function xhrRetrieve(projID) { 
    var xhr = new XMLHttpRequest(); 

    xhr.onreadystatechange = function() { 
     if(xhr.readyState == 4) { 
      if(xhr.status == 200) { 
       var obj = $.parseJSON(xhr.responseText); 

       doStuffWithTheAjaxResponse(obj.select.toString()); 
      } 
     } 
    } 

    var url = "ajax.cgi"; 
    var data = "action=retrieve-opp&proj-id=" + projID; 

    xhr.open("POST",url); 
    xhr.setRequestHeader("Content-Type","application/x-www-urlencoded"); 
    xhr.send(data); 

} 
0

函數xhrRetrieve沒有返回值。你期望發生什麼?

+0

沒有了'返回obj.select.toString();'內'xhr.onreadystatechange'實現這一目標? – daniel0mullins

+0

不,只有當XHR事件被觸發時纔會發生。如果你想阻塞呼叫,你需要在調用xhr.send時設置async = false;或者更好地使用異步解決方案,比如Bjorn發佈的片段。 – Mikola

0

你有兩個功能在那裏。內部函數返回一個值,但不是外部函數。內部函數是一個事件處理程序,所以返回值不會去任何地方。你的XMLHttpRequest是異步的,所以你不會馬上得到一個返回值。請參閱此帖以獲得更詳細的解釋:parameter "true" in xmlHttpRequest .open() method

1

由於請求是異步的,因此函數將在onreadestatechange中的代碼觸發之前返回。您可以切換到同步,並獲得函數返回前值:

function xhrRetrieve(projID) { 
    var returnVal; 
    var xhr = new XMLHttpRequest(); 

    var url = "ajax.cgi"; 
    var data = "action=retrieve-opp&proj-id=" + projID; 

    //3rd param is false to switch to synchronous 
    xhr.open("POST",url, false); 
    xhr.setRequestHeader("Content-Type","application/x-www-urlencoded"); 
    xhr.send(data); 
    if(xhr.readyState == 4) { 
     if(xhr.status == 200) { 
      var obj = $.parseJSON(xhr.responseText); 
      return obj.select.toString(); 
     } 
    } 
}