2011-03-19 60 views
12

我是JavaScript編程新手。我現在正在研究我的Google Chrome擴展程序。這是不起作用的代碼...:P如何讓XHR.onreadystatechange返回結果?

我想要getURLInfo函數返回它的JSON對象,並且想把它放入resp。有人可以修復我的代碼,讓它工作嗎?

在此先感謝。

回答

21

你正在處理一個異步函數調用這裏。結果在到達時處理,而不是在函數結束運行時處理。

這就是回調函數的用途。結果可用時調用它們。

function get(url, callback) { 
    var xhr = new XMLHttpRequest(); 
    xhr.open("GET", url, true); 
    xhr.onreadystatechange = function() { 
     if (xhr.readyState == 4) { 
      // defensive check 
      if (typeof callback === "function") { 
       // apply() sets the meaning of "this" in the callback 
       callback.apply(xhr); 
      } 
     } 
    }; 
    xhr.send(); 
} 
// ---------------------------------------------------------------------------- 


var param = "http://example.com/";     /* do NOT use escape() */ 
var finalUrl = "http://RESTfulAPI/info.json?url=" + encodeURIComponent(param); 

// get() completes immediately... 
get(finalUrl, 
    // ...however, this callback is invoked AFTER the response arrives 
    function() { 
     // "this" is the XHR object here! 
     var resp = JSON.parse(this.responseText); 

     // now do something with resp 
     alert(resp); 
    } 
); 

注:

  • escape()永遠以來已被棄用。不要使用它,它不能正常工作。使用encodeURIComponent()
  • 可以使send()呼叫同步,由open()async參數設置爲false。這會導致您的UI在請求運行時被凍結,而您不希望這樣做。
  • 有許多庫已經被設計成使Ajax請求變得簡單和多功能。我建議使用其中之一。
3

對於異步XHR調用,您完全不能這樣做。您無法讓JavaScript「等待」來自服務器的HTTP響應;你所能做的就是將運行時系統作爲一個函數來調用(你的處理程序),它會調用它。但是,在設置XHR的代碼完成之後,該呼叫將長達長時間

然而,所有不會丟失,因爲該處理函數可以做什麼。無論你想用返回值做什麼,你都可以在裏執行處理程序(或者從處理程序中調用的其他函數)。

因此,在你的榜樣,你會改變這樣的事情:

xhr.onreadystatechange = function() 
    { 
     if (xhr.readyState == 4) 
     { 
      var resp = JSON.parse(xhr.responseText); 
      // 
      // ... whatever you need to do with "resp" ... 
      // 
     } 
    } 
} 
-1

對於小編輯在談論後:https://stackoverflow.com/a/5362513/4766489

... 
if (typeof callback == "function") { 
    //var resp = xhr.responseText; 
    var resp = JSON.parse(xhr.responseText); 
    callback(resp); 
} 
... 

當你罵

... 
function(data) { 
    alert(data); 
    /* now do something with resp */ 
} 
...