如何执行“;“同步”;javascript调用服务器而不锁定浏览器

How to execute "synchronous" javascript call to server without locking up the browser

本文关键字:调用 javascript 服务器 锁定浏览器 同步 执行 何执行      更新时间:2024-03-01

这可能是一个愚蠢的问题,但是。。。。在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

请注意setTimeoutsetInterval是不可接受的解决方案,需要的是如上所述的直接执行。最终,在回调之后,在对服务器的调用完成时继续执行也是可以的(见下文)。

我在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生成器来模拟异步函数的非阻塞同步执行。请参见此处。然而,浏览器对此的支持仍然有限。

Webworker示例:

工人

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");

也可以在不需要单独文件的情况下使用Webworker,如本文所述。

这可能是个愚蠢的问题,但是。。。。在Javascript中有办法同步等待特定请求完成而不锁定浏览器线程?

不,同步代码无法做到这一点。异步代码和AJAX的全部目的就是解决这个问题。