首页 > 解决方案 > Javascript getJSON将参数存储为函数范围问题之外的变量

问题描述

尝试通过 getJSON 从 URL 返回 id='alert' 的日期值。即使将 async 设置为 False,getJSON 似乎也无法正常工作。我从另一个正常工作的脚本中获取了这段代码。

<!DOCTYPE html>
<html>
<body>


<p><input type="text" id="input" value="100 | 47.6735" rows="30" cols="50"></p>

<button class="btn btn-primary btn-lg" onclick="getAlert()">Get Date Alert</button>

<p id="alert"></p>

<script>

$.ajaxSetup({
    async: false
  });

function getJSON_data(url){
  var date = '1'
  $.getJSON(
    url,
    function(data) {
    var date = data.date
    });  
  
  return {'test':date}
}

function getAlert() {

  var str = document.getElementById("input").value;;
  var res = str.split(" | ");
  var id = res[0];

  var url = 'http://date.jsontest.com/'
 
  var alert = getJSON_data(url).test;
  document.getElementById("alert").innerHTML = alert;
}

</script>

</body>
</html>

向脚本的 js 部分添加了 Async 和 Promises。在“警报”部分无法完全确定返回的日期。

...

function getJSON_data(url){
  return new Promise((resolve, reject) => {
    $.getJSON(
      url,
      function({date}) {
        resolve({test: date})
      });
    })
  })
}

function getAlert() {

  var str = document.getElementById("input").value;
  var res = str.split(" | ");
  var id = res[0];
 
  var url = 'http://date.jsontest.com/';

  var alert = (await getJSON_data(url)).test;
  document.getElementById("alert").innerHTML = alert
}

...

标签: javascripthtmlapigetjson

解决方案


首先,请永远,绝对永远不要使用 syncronouse ajax,因为很久以前,asyncronouse requests 是为了减少很多痛苦而成立的)

其次,您应该了解函数范围和闭包概念:

var globalVar = "some value"

function foo() {
  var varInClosure = "some other value"
  console.log(
    "here we have acces to global var:", globalVar, // some value
    "\nand local var:", varInScope // some other value
  ) 
}

console.log(
  "here we have access only to var in same scope", globalVar, // some value
  "\nbut not to var from other scope", varInScope // undefined
)

在您的情况下,您可以选择一种方式,丑陋但有效,使用全局变量,或者正确和现代 - 使用async/await和 promise:

function getJSON_data(url){
  return new Promise((resolve, reject) => {
    $.getJSON(
      url,
      function({date}) {
        resolve({test: date})
      });
    })
  })
}

//....

var alert = (await getJSON_data(url)).test;
document.getElementById("alert").innerHTML = alert;

推荐阅读