[英]Scope for using a JS variable set by an asynchronous call
我已閱讀如何從異步調用返回響應? 並了解 JavaScript 中異步調用的性質。
使用 jQuery 3.2.1,我有一些代碼可以對端點/get-data
進行 ajax 調用,它返回一個帶有屬性和值的 JSON 結構,例如
{ "download_list_groups_limit" : 2 }
如果 JSON 響應不包含屬性download_list_groups_limit
那么我返回一個默認值,在這種情況下是10
(見下面的代碼)。
這意味着我要么有 ajax 響應的結果(在本例中為2
),要么有默認值 10。
我想將結果分配給一個名為download_list_groups_limit
的變量。
我理解 JavaScript 的異步性質意味着對/get-data
的 ajax 調用必須在結果可用之前完成。
我有以下代碼:
var download_list_groups_limit = getSubstanceLimits(function(result) {
console.log('result = ' + result);
});
console.log('download_list_groups_limit = ' + download_list_groups_limit);
function getSubstanceLimits(callback) {
let filtered_response;
$.ajax({
url : '/get-data',
success: function(response) {
if (response.download_list_groups_limit) {
filtered_response = response.download_list_groups_limit; // 2 in this example
} else {
filtered_response = 10; // Default
}
callback(filtered_response);
}
});
}
console.log
語句返回以下內容:
download_list_groups_limit = undefined
result = 2
我的問題是關於范圍:如果我想在腳本的全局范圍內使用我的result
(例如分配一個變量並將其設置為2
)我該怎么做? 似乎我唯一能做的就是在回調里面,即在getSubstanceLimits(function(result) { ... });
如果我需要在腳本中各個點的回調之外使用值 2,這怎么可能?
更改腳本的入口點,以便getSubstanceLimits
在其他任何事情之前首先被調用。 在回調中,調用您之前的入口點,該入口點運行您腳本的其余部分。 你可以這樣做:
function getSubstanceLimits(callback) {
$.ajax({
url: '/get-data',
success: function (response) {
callback(response.download_list_groups_limit || 10);
}
});
}
而不是您之前的入口點,例如:
runApp();
做
getSubstanceLimits(runApp);
function runApp(result) {
// code here that uses async `result`
}
您的整個應用程序不必在回調中,但是您需要依賴result
任何地方都需要在回調中。
您還可以使用 jQuery then-able 而不是使用回調。
這不是范圍問題。 如果您只關心將結果分配給全局變量的范圍確實有效。
這是一個證明它有效的示例。 我正在用每秒記錄一次替換單個console.log()
:
var download_list_groups_limit;
getSubstanceLimits(function(result) {
download_list_groups_limit = result;
console.log('result = ' + result);
});
setInterval(function(){
console.log('download_list_groups_limit = ' + download_list_groups_limit);
}, 1000);
您肯定會看到在某個時間點download_list_groups_limit
將更改為result
的值。
它不適用於您測試的代碼的唯一原因是您太早記錄了download_list_groups_limit
。 (當然,假設您將作業修復為像我的示例一樣)。
如果你對依賴於download_list_groups_limit
代碼沒問題,直到它獲得正確的值,那么你可以簡單地做我上面所做的。 如果這對您來說getSubstanceLimits
那么您需要將其余代碼放在getSubstanceLimits
的回調中。 你真的需要改變你對如何設計程序流程的想法。
有幾個設計模式和語言功能,可以使異步代碼更易於管理,但你真的需要了解事情的時候在JavaScript中發生。 如果您熟悉 C++ 和 Java 等語言,那么您對作用域的理解應該已經正確。 但是,你的事情時有發生需要改進的理解:
// THIS HAPPENS FIRST
var download_list_groups_limit;
// THIS HAPPENS SECOND
getSubstanceLimits(function(result) {
// THINGS IN HERE HAPPENS LAST
// AFTER END OF ALL CODE IN ALL FILES
download_list_groups_limit = result;
console.log('result = ' + result);
});
// THIS HAPPENS THIRD
console.log('download_list_groups_limit = ' + download_list_groups_limit);
// END OF CODE HAPPENS FOURTH
在你習慣了思考未來發生的事情后,我建議你看看Promise
s、 async/await
(使用Promise
)、事件監聽器和 Observables 等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.