如何在不锁定浏览器的情况下执行对服务器的 "synchronous" javascript 调用
How to execute "synchronous" javascript call to server without locking up the browser
这可能是个愚蠢的问题,但是....在 Javascript 中有没有办法在不锁定浏览器线程的情况下同步等待特定请求完成?
目标是使用 ajax 调用服务器端并在调用完成后执行一段代码并避免回调(地狱)。
像这样的一些简单的代码。
// 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;
}
通过 Internet、Whosebug 和论坛,每个人似乎都想要这个,但没有浏览器看起来可以实现它
this may be a stupid question, but....is there a way in Javascript to
synchronously wait for a specific request to finish without locking
the browser thread?
不,无法使用同步代码执行此操作。异步代码和 AJAX 的全部目的就是解决这个问题。
您可以通过 Webworker 发出请求来实现不阻塞 UI 线程的同步 HTTP 请求。但是,将结果传回 UI 线程仍然是异步的。此外,Webworker 的启动需要时间和内存成本,所以请记住这一点。
另一种可能性是使用 ES6 Generators to simulate non-blocking synchronous execution of async functions. See here。但是,浏览器对此的支持仍然有限。
网络工作者示例:
工人
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 中有没有办法在不锁定浏览器线程的情况下同步等待特定请求完成?
目标是使用 ajax 调用服务器端并在调用完成后执行一段代码并避免回调(地狱)。 像这样的一些简单的代码。
// 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;
}
通过 Internet、Whosebug 和论坛,每个人似乎都想要这个,但没有浏览器看起来可以实现它
this may be a stupid question, but....is there a way in Javascript to synchronously wait for a specific request to finish without locking the browser thread?
不,无法使用同步代码执行此操作。异步代码和 AJAX 的全部目的就是解决这个问题。
您可以通过 Webworker 发出请求来实现不阻塞 UI 线程的同步 HTTP 请求。但是,将结果传回 UI 线程仍然是异步的。此外,Webworker 的启动需要时间和内存成本,所以请记住这一点。
另一种可能性是使用 ES6 Generators to simulate non-blocking synchronous execution of async functions. See here。但是,浏览器对此的支持仍然有限。
网络工作者示例:
工人
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 所述。