2014-12-07 81 views
1

在嘗試學習如何使用JavaScript Promises時,我嘗試實現一個函數,該函數可以將XHR的結果分配給一個變量。我知道這可能不完全是這種慣用的方式。儘管如此,如果我遇到困惑的問題,這是一件有趣的事情。將變量作爲參數傳遞給函數併爲其分配新值?

這個想法是將XHR包裝在Promise中,並傳遞一個將XHR響應分配給變量的解析函數。以下是一些代碼,並附有說明。一切以測試它在控制檯是在這裏:

function getJSON(url) { 
    return new Promise(function(resolve, reject) { 
    var xhr = new XMLHttpRequest(); 
    xhr.open("get", url); 
    xhr.onreadystatechange = function() { 
     if (xhr.readyState == 4 && xhr.status < 400) { 
     resolve(xhr.responseText); 
     } 
    }; 
    xhr.send(); 
    }); 
} 

function assignDataTo(target, url, ctx) { 
    // Asynchronously assign JSON response to `target` variable 
    getJSON(url) 
    .then(function(data) { 
     ctx.target = JSON.parse(data); 
     }, function(error) { 
     console.log(error); 
     } 
    ); 
} 

var targetVariable, 
    url = "https://data.baltimorecity.gov/resource/n4ma-fj3m.json?$select=*&$limit=5"; 

assignDataTo(targetVariable, url, window); 
valueOf(targetVariable); // Error: undefined 
valueOf(window.target); // JSON: xhr.response 

添加上下文參數向assignDataTo是企圖更具體地約可變接收數據的範圍。我發現ctx.target(或​​)的計算結果爲window.target,而不是像我希望的那樣替換函數參數(即ctx.target == window.targetVariable)。

如何將指針傳遞給我想要分配的實際變量,作爲assignDataTo函數的參數? (其次,對這個使用承諾進行工作的總體策略的任何意見都是值得歡迎的。)

+0

這:http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing – zerkms 2014-12-07 08:18:47

回答

2

字符串,布爾值和數字通過javascript中的值傳遞。但是,您可以將targetVariable包裝在可通過引用傳遞的對象中。

ctx.target = JSON.parse(data);實際上只是設置在ctx對象的關鍵target,這將是你的情況window對象的值。它與作爲參數傳遞給函數的參數target無關。

另外你的assignDataTo()函數異步運行,所以調用valueOf(targetVariable)不會工作,因爲承諾可能還沒有解決,即。 XHR的結果尚未到達。更好的解決方案就是這樣的。

function assignDataTo(url) { 
    // Return a Promise 
    return getJSON(url) 
    .then(function(data) { 
     //resolve the Promise with this value 
     return JSON.parse(data); 
    }, function(error) { 
     console.log(error); 
    } 
); 
} 

var targetVariable; 
//wait for the Promise to be resolved and then assign the variable and do whatever with it 
assignDataTo(url).then(function(result) { 
    targetVariable = result; 
    valueOf(targetVariable); 
}); 
+0

迂迴評論:字符串,布爾值和數字等在JavaScript中不是對象,它們是值。 – 2014-12-07 09:26:13

0

JavaScript並沒有明確的引用(或指針)在其它語言(例如:PHP & $變量),但對象時,它使用的引用。

向一個函數發送一個數組(也是JavaScript中的對象)時,它將得到與該數組相同的引用。這就是爲什麼在該功能內部進行的任何更改將在外部提供。

實施例:

function addEl(arr) { 
    arr.push(3); 
} 

var ourArray = [1, 2]; // [1, 2] 
addEl(ourArray); 
console.log(ourArray); // [1, 2, 3] 

此正常工作與對象,但它是不同的,當涉及到原始類型:字符串,數字或布爾值。 當向一個函數發送一個基元時,它創建它的一個副本,所以它不會從該函數外部改變基元。

實施例與圖元:

function increment(el) { 
    el += 1; 
} 

var numb = 1; 
increment(numb); 
console.log(numb); // 1 

同樣的事情在您的代碼:

targetVariable 

是一個原始變量和

window 

是一個對象。

寫入時:

ctx.target 

你實際上是添加新的參數,以CTX(參考窗口)。如果你想改變 'targetVariable',在你的函數,你應該分配JSON.parse(數據)window.targetVariable:

function assignDataTo(url, ctx) { 
    // Asynchronously assign JSON response to `target` variable 
    getJSON(url) 
    .then(function(data) { 
     ctx.targetVariable = JSON.parse(data); 
    }, function(error) { 
     console.log(error); 
    } 
); 
} 
// ... 
assignDataTo(url, window); 
相關問題