簡體   English   中英

使用由異步調用設置的 JS 變量的范圍

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM