这可能是一个愚蠢的问题,但是......Javascript中有没有一种方法可以同步等待特定请求完成而不锁定浏览器线程?
目标是使用 ajax 调用服务器端并在调用完成后执行一段代码并避免回调( hell )。 像这样的一些简单的代码。
// some js code
var result = doServerCall(); // w/out (b)locking the browser thread -> browser must remain responsive
// some js code to process the result
请注意 setTimeout 和 setInterval 不是可接受的解决方案,需要的是如上所述的直接执行。最终,在调用服务器完成后继续执行的回调也是可以的(见下文)。
我在 Firefox 插件中使用了以下内容(这并不完全是我想要的,但仍然是一个可接受的解决方案)。
globalDone = false;
// some js code
doServerCall(); // asynchrnonous call here, the callback is below
var thread = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager).currentThread;
while ( globalDone === false ) {
thread.processNextEvent(true);
}
// some js code to process the result
回调
function processResponse ( xhrResponse ) {
globalResult = xhrResponse;
globalDone = true;
}
通过互联网、StackOverflow 和论坛,似乎每个人都想要这个,但没有浏览器愿意实现它
最佳答案
您可以通过从 Webworker 发出请求来实现同步 HTTP 请求,这不会阻塞 UI 线程。然而,将结果传送回 UI 线程仍然是异步的。另外,Webworker 的启动需要时间和内存成本,因此请记住这一点。
另一种可能性是使用 ES6 Generators模拟异步函数的非阻塞同步执行。 See here 。但是,浏览器对此的支持仍然有限。
网络 worker 示例:
worker
self.onmessage = function (event) {
if (event.data === "init") {
var xhr = new XMLHttpRequest();
xhr.open("GET", "foo.com", false); // false means non-async
xhr.send(null);
var result = xhr.responseText;
// do stuff with result...
self.postMessage(result); // pass result
self.close(); // terminate self
}
};
主要脚本
var worker = new Worker("myWorker.js");
worker.onmessage = function (event) {
console.log(event.data);
};
worker.postMessage("init");
Webworkers 也可以在不需要单独文件的情况下使用,如 here 中所述。 .
关于javascript - 如何在不锁定浏览器的情况下对服务器执行 "synchronous"javascript调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28660918/