2014-07-24 21 views
0

我試圖把一個XMLHttpRequest到這樣將XMLhttpRequest轉換爲函數失敗:異步或其他?

var getImageBase64 = function (url) { // code function 
    var xhr = new XMLHttpRequest(url); 
    ... // code to load file 
    ... // code to convert data to base64 
    return wanted_result; // return result of conversion 
} 
var newData = getImageBase64('http://fiddle.jshell.net/img/logo.png'); // function call 
doSomethingWithData($("#hook"), newData); // reinjecting newData in wanted place. 

我'成功加載該文件,並轉換爲Base64的功能。然而我'consistenly failling 得到的結果作爲輸出

var getImageBase64 = function (url) { 
    // 1. Loading file from url: 
    var xhr = new XMLHttpRequest(url); 
    xhr.open('GET', url, true); // url is the url of a PNG image. 
    xhr.responseType = 'arraybuffer'; 
    xhr.onload = function(e) { 
     if (this.status == 200) { // 2. When loaded, do: 
      console.log("1:Response?> " + this.response); // print-check xhr response 
      var imgBase64 = converterEngine(this.response); // converter 
     } 
    } 
    xhr.send(); 
    return xhr.onload(); // <fails> to get imgBase64 value as the function's result. 
} 

console.log("4>>> " + getImageBase64('http://fiddle.jshell.net/img/logo.png')) // THIS SHOULD PRINT THE BASE64 CODE (returned resukt of the function getImageBase64) 

Fiddle here

如何使它工作,因此它返回新的數據作爲輸出?


解決方案:我的最終實現是visible here,並JS: how to load a bitmap image and get its base64 code?

+0

是的,這就是事情的異步工作。手動調用'onload'不會實際加載請求。您可以將回調傳遞給'getImageBase64'並在'onload'中回調,或返回[promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise )。 – Ryan

回答

1

JavaScript中的異步調用(如xhr)不能像常規函數那樣返回值。編寫異步功能時使用的常見模式是這樣的:

function asyncFunc(param1, param2, callback) { 
    var result = doSomething(); 
    callback(result); 
} 

asyncFunc('foo', 'bar', function(result) { 
    // result is what you want 
}); 

所以,你的例子翻譯如下所示:

var getImageBase64 = function (url, callback) { 
    var xhr = new XMLHttpRequest(url); 
    ... // code to load file 
    ... // code to convert data to base64 
    callback(wanted_result); 
} 
getImageBase64('http://fiddle.jshell.net/img/logo.png', function(newData) { 
    doSomethingWithData($("#hook"), newData); 
}); 
1

當您使用xhr.onload您的實際定義一個函數JS來時,它調用加載,因此xhr.onload的值不是函數的輸出。返回xhr.onload()將調用該函數並返回輸出,但是你的onload函數沒有返回語句,因此沒有輸出。此外,您在設置對象時同步調用xhr.onload,因此它不會處理任何數據。

我建議你爲你的函數添加一個回調參數,就像這樣,當數據加載完成後,它就會執行。

function getImageBase64(url, callback) { 
    // 1. Loading file from url: 
    var xhr = new XMLHttpRequest(url); 
    xhr.open('GET', url, true); // url is the url of a PNG image. 
    xhr.responseType = 'arraybuffer'; 
    xhr.callback = callback; 
    xhr.onload = function(e) { 
     if (this.status == 200) { // 2. When loaded, do: 
      console.log("1:Response?> " + this.response); // print-check xhr response 
      var imgBase64 = converterEngine(this.response); // converter 
      this.callback(imgBase64);//execute callback function with data 
     } 
    } 
    xhr.send(); 
} 

那麼你可以使用它像這樣

var myCallBack = function(data){ 
    alert(data); 
}; 
getImageBase64('http://fiddle.jshell.net/img/logo.png', myCallBack); 
+0

我嘗試從函數getImageBase64()中得到結果值。但'var res = getImageBase64('http://fiddle.jshell.net/img/logo.png',myCallBack);'仍然不是我的新數據。 – Hugolpz

+0

函數的輸出不會是響應數據,也不會有返回語句。您可以將處理後的數據存儲在xhr對象中並返回該數據,但由於這是異步調用,您必須等待回調觸發,然後才能訪問數據。你是否嘗試過示例代碼?回調中的數據參數就是你想要的變量。 – nepeo

相關問題