JavaScript: Ajax请求后的全局变量

65

问题相当简单和技术性:

var it_works = false;

$.post("some_file.php", '', function(data) {

     it_works = true;

});

alert(it_works); # false (yes, that 'alert' has to be here and not inside $.post itself)

我想要实现的是:

alert(it_works); # true
有没有办法做到这一点?如果不行,$.post()能否返回一个值应用到it_works中?

3
请参考以下链接:https://dev59.com/N3VC5IYBdhLWcg3w9GPM想要让 jQuery 执行同步而非异步的 AJAX 请求,请按照上述链接中的方法进行操作。切记,同步请求会阻塞浏览器,因此只有在必要时才使用它们。 - Crescent Fresh
4个回答

107
你期望的是同步阻塞)类型的请求。
var it_works = false;

jQuery.ajax({
  type: "POST",
  url: 'some_file.php',
  success: function (data) {
    it_works = true;
  }, 
  async: false // <- this turns it into synchronous
});​

// Execution is BLOCKED until request finishes.

// it_works is available
alert(it_works);

默认情况下,请求是异步非阻塞)的,这意味着浏览器不会等待它们完成以继续工作。这就是为什么您的警报得到了错误的结果。

现在,使用jQuery.ajax,您可以选择将请求设置为同步,这意味着脚本将只在请求完成后继续运行。


然而,推荐的方法是重构您的代码,使数据在请求完成后立即传递给回调函数。这是首选的,因为阻塞执行意味着阻塞UI,这是不可接受的。请按照以下方式进行操作:

$.post("some_file.php", '', function(data) {
    iDependOnMyParameter(data);
});

function iDependOnMyParameter(param) {
    // You should do your work here that depends on the result of the request!
    alert(param)
}

// All code here should be INDEPENDENT of the result of your AJAX request
// ...

异步编程稍微复杂一些,因为请求的结果被封装在函数中,而不是遵循请求语句。但是用户体验的实时行为可以得到显著改善,因为他们将不会看到缓慢的服务器或网络导致浏览器崩溃。在面向人员使用的应用程序中同步编程不妥当不应该采用

Douglas Crockford (YUI 博客)


4
请注意,如果some_file.php执行了大量(昂贵的)操作,这将会影响可用性。 - Felix Kling
1
@Felix 是的,但有些情况下同步 I/O 是必不可少的。它是一种不应过度使用的工具。最好避免使用,可以这么说。 - gblazex
2
@galambalazs:同步请求已被弃用,标准现在指出使用它们将会抛出错误。 - user2284570
1
Chrome控制台消息:“在主线程上同步XMLHttpRequest已被弃用,因为它对最终用户的体验有害。” - Stefan
耶...太棒了,异步:false..谢谢。 - UJS
显示剩余3条评论

7
AJAX代表异步JavaScript和XML。因此,向服务器的提交与其他函数不同步。相反,可以尝试使用以下代码(它将简写的$.post拆分为更长的$.ajax调用,并添加了async选项)。
var it_works = false;

$.ajax({
  type: 'POST',
  async: false,
  url: "some_file.php",
  data: "",
  success: function() {it_works = true;}
});

alert(it_works);

希望这可以帮到你!

5

看起来你的问题只是一个并发问题。post函数需要传入一个回调参数,用于在post完成时通知你。你不能像这样在全局作用域中创建alert并期望post已经完成。你必须将它移动到回调函数中。


4
您的代码失败的原因是因为post()将启动一个异步请求到服务器。这对您来说意味着post()会立即返回,而不是像您期望的那样在请求完成后返回。
因此,您需要的是请求同步并阻塞当前线程,直到请求完成。
var it_works = false;

$.ajax({
  url: 'some_file.php',
  async: false,  # makes request synchronous
  success: function() {
    it_works = true;
  }
});

alert(it_works);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接