2010-09-21 52 views
10

JavaScript中有一种方法可以将HTTP请求发送到HTTP服务器,并等到服务器回复回复?我希望我的程序等待,直到服务器回复并且不执行任何其他在此请求之后的命令。如果HTTP服务器关闭,我希望HTTP请求在超时后重复,直到服务器回复,然后程序的执行可以正常继续。如何强制程序等待HTTP请求在JavaScript中完成?

任何想法?

谢谢你在前进, Thanasis

+6

我真的希望,当他们的人会离开解释性意见-1。 – kojiro 2011-12-30 20:54:54

回答

10

可以执行同步请求。 jQuery示例:

$(function() { 
    $.ajax({ 
     async: false, 
     // other parameters 
    }); 
}); 

您应该看看jQuery的AJAX API。我强烈建议使用像jQuery这样的框架。手动进行跨浏览器ajax是一个真正的痛苦!

+0

这是最好的方法!但是,很多人认为JS框架是邪恶的,并且倾向于自己编写一切代码。 – Alex 2010-09-21 12:44:39

+0

我试图用多种方式使用XmlHttpRequest来做到这一点,但我没有找到一种方法,以便停止执行,直到我得到一个回应。 – 2010-09-21 12:45:04

+4

亚历克斯,这就是我!我就是其中之一! ;) – 2010-09-21 12:45:56

0

为此,您可以在页面开始加载后立即在JavaScript中启动加载程序,然后可以在请求结束或您的dom准备好时关闭它。 我想说的是,当页面加载开始时,启动一个加载器。然后页面可以使用ajax执行多个同步请求,直到除非您没有得到响应,否则不要关闭关闭加载器。 在最终调用中收到所需的响应后,可以关闭加载程序。

+1

你离开...他是询问拖延多个请求。 – Alex 2010-09-21 12:46:26

+0

是的,这正是我想要做的。 – 2010-09-21 12:49:03

+0

@Thanasis Petsas:请检查已编辑的帖子。希望这可以帮到你。 – Nik 2010-09-21 13:19:35

2

您可以使用XMLHttpRequest对象发送您的请求。一旦你发送你的请求,你可以通过readyState属性来识别状态。 readyState将具有以下不同的状态。

  • 初始化 - 还没有开始加载但
  • 装载 - 是否加载
  • 互动 - 装入足够,并且用户可以用它
  • 完整的互动 - 满载

例如:

xmlhttp.open("GET","somepage.xml",true); 
xmlhttp.onreadystatechange = checkData; 
xmlhttp.send(null); 

function checkData() 
{ 
    alert(xmlhttp.readyState); 
} 

希望这个将有助于

+0

我想要程序的执行是串行的,我不想使用回调。我希望如果可能的话,在“xmlhttp.send(null);”停止执行程序呼叫,然后在请求完成后继续。 – 2010-09-21 13:00:43

+0

你可以玩readyState属性。也许你可以把它放在while循环中,这样它就不会进入下一行,直到执行结束。另外,如果您可以预测执行时间,则可以使用setTimeOut()函数。更多关于这个功能,你可以在这里阅读。 http://www.w3schools.com/jsref/met_win_settimeout.asp – Akie 2010-09-22 05:13:40

0

我在使用Three.js和Google Closure构建的游戏中也有类似的情况。我必须加载2个资源,Three和Closure不允许我使这些同步。

起初,我天真地写道:

main() { 

    ... 
    var loaded=0; 
    ... 

    // Load Three geometry 
    var loader = new THREE.JSONLoader(); 
    loader.load("x/data.three.json", function(geometry) { 
    ... 
    loaded++; 
    }); 

    // Load my engine data 
    goog.net.XhrIo.send("x/data.engine.json", function(e) { 
    var obj = e.target.getResponseJson(); 
    ... 
    loaded++; 
    }); 

    // Wait for callbacks to complete 
    while(loaded<2) {} 

    // Initiate an animation loop 
    ... 
}; 

是等待回调从来没有完成结束,从环loaded永远无法加点的循环。问题是直到main返回(至少在Chrome上),才会触发回调。

一个解决方案可能是检查两个回调是否是最后一个完成,然后继续启动动画循环。

另一个解决方案 - 或许更直接回答你问(如何等待每个负载启动另一前) - 将巢回调如下:

// Load Three geometry 
var loader = new THREE.JSONLoader(); 
loader.load("x/data.three.json", function(geometry) { 
    ... 

    // Load my engine data 
    goog.net.XhrIo.send("x/data.engine.json", function(e) { 
    var obj = e.target.getResponseJson(); 
    ... 

    // Initiate an animation loop 
    ... 

    }); 
    }); 
}; 
+1

嗨Argenti,欢迎来到stackoverflow!请尽可能清楚地回答你的答案。使用大括号或使用\“字符包装您的代码。如果可能,请尝试在发布之前查看是否可以运行某些内容。这些问题也可能在未来提及,所以请尽量努力! – 2011-12-30 15:09:02

+0

我发现这个:注意:从Gecko 30.0(Firefox 30.0/Thunderbird 30.0/SeaMonkey 2.27)开始,由于对用户体验的负面影响,主线程上的同步请求已被弃用。 ://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) – 2014-12-23 19:41:05

18

还有第三个参数到XmlHttpRequest :: open(),它旨在表明你希望通过异步方式发送请求(并通过onreadystate处理程序处理响应)。因此,如果你希望它是同步的(即等待答案),只需为该第三个参数指定false即可。 在这种情况下,您可能还想为您的请求设置有限的超时属性,因为它会阻止页面直到接收。

下面是两个同步和异步的所有功能于一身的样本函数:

function httpRequest(address, reqType, asyncProc) { 
    var r = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"); 
    if (asyncProc) 
     r.onreadystatechange = function() { 
      if (this.readyState == 4) asyncProc(this); 
     }; 
    else 
     r.timeout = 4000; // Reduce default 2mn-like timeout to 4 s if synchronous 
    r.open(reqType, address, !(!asyncProc)); 
    r.send(); 
    return r; 
} 

,你可以调用这个方法:

var req = httpRequest("http://example.com/aPageToTestForExistence.html", "HEAD"); // In this example you don't want to GET the full page contents 
alert(req.status == 200 ? "found!" : "failed"); // We didn't provided an async proc so this will be executed after request completion only 
+0

这将我引向异步库,这使得这非常简单。 https://github.com/caolan/async/不要被包装垃圾所愚弄。您只需包含一个小小的JavaScript文件 - async.js! – tudor 2015-02-12 03:37:04