对一组JavaScript文件的同步请求。JavaScript中的sleep()

对一组JavaScript文件的同步请求。JavaScript中的sleep(),javascript,ajax,asynchronous,sleep,synchronous,Javascript,Ajax,Asynchronous,Sleep,Synchronous,我希望允许我的JavaScript数据包请求(同步ajax调用)其他JavaScript数据包: // 2 sequential synchronous calls framework.require('packet1'); // time1 ms framework.require('packet2'); // time2 ms // use packets 这两个请求的处理时间为time1+time2毫秒。因此,还有另一个想法:每一个请求都是异步的,但要保证所有请求都是同步处理的: //

我希望允许我的JavaScript数据包请求(同步ajax调用)其他JavaScript数据包:

// 2 sequential synchronous calls
framework.require('packet1'); // time1 ms
framework.require('packet2'); // time2 ms
// use packets
这两个请求的处理时间为time1+time2毫秒。因此,还有另一个想法:每一个请求都是异步的,但要保证所有请求都是同步处理的:

// 2 parallel asynchronous calls, synchronous in total
framework.require([
    'packet1', // time1 ms
    'packet2'  // time2 ms
]);
// use packets
据我所知,这应该更快。现在让我们看看我的实现:

framework = {
    require_counter:0,
    require: function(arr)
    {
        framework.require_counter = arr.length;

        var success = function(data, textStatus, jqXHR)
        {
            framework.require_counter -= 1;
        }
        var error = function(jqXHR, textStatus, errorThrown)
        {
            framework.require_counter -= 1;
            // some error notification
        }

        // asynchronous calls
        for (var i = 0; i < arr_js.length; i++)
            $.ajax({
                url: arr_js[i],
                success: success,
                error: error
            });

        // wait
        while (framework.require_counter > 0)
            framework.wait();

        // finally return
    }
}
framework={
需要\u计数器:0,
要求:功能(arr)
{
framework.require_counter=arr.length;
var success=函数(数据、文本状态、jqXHR)
{
framework.require_counter-=1;
}
var error=函数(jqXHR、textStatus、ERRORSHORN)
{
framework.require_counter-=1;
//一些错误通知
}
//异步调用
对于(var i=0;i0)
framework.wait();
//最后返回
}
}
最棘手的部分是实现wait()函数。JavaScript不提供一个;应该找到另一种解决办法。异步setTimeout()不是答案。这就是我的问题:如何实现wait()函数?或者可能有另一个通用的解决方案


我尝试过这种方法:。也许您会指出没有服务器依赖性的更“简洁”的解决方案。

如果您确实需要同步请求,您通常可以指导底层AJAX机制这样做。例如,在jQuery中,您将
async
设置为false。使用XMLHttpRequest时,将false作为第三个参数传递给(这就是Raman在您链接到的博客文章中实现睡眠的方式)。然而,SJAX通常是一件坏事,因为它会阻止当前浏览器中的JS执行。更好的方法是使用,传递表示要运行的其余计算的函数:

framework = {
    require: function(urls, done)
    {
        function success(data, textStatus, jqXHR)
        {
            //...
        }
        function error(jqXHR, textStatus, errorThrown)
        {
            //...
        }

        urls.unshift('');
        function load() {
            urls.shift();
            if (urls.length) {
                $.ajax({
                    url: urls[0],
                    // here are some continuations
                    complete: load,
                    success: success,
                    error: error
                });
            } else {
                // here's a continuation invocation
                done();
            }
        }
    }
};
如果在加载所有给定资源时需要执行某些操作,而不是同步性,则可以对操作使用延续,但不能对资源加载使用延续。相反,您只需应用一个事件处理模型,记录每个加载的完成情况,并在所有资源请求完成时调用依赖操作

framework = {
    require: function(urls, done)
    {
        var remaining = urls.length;
        var failed=[];
        // The following implementation is vulnerable to race conditions.
        // Good thing JS isn't generally multithreaded. If (when) it is,
        // and if the browser doesn't offer some form of synchronization,
        // then Peterson's algorithm should work correctly if inefficiently.
        function success(data, textStatus, jqXHR) {
            if (!--remaining) { // critical section
                done(failed);
            }
        }
        function makeErrorHandler(url) {
            return function (jqXHR, textStatus, errorThrown) {
                failed.push(url);
                if (!--remaining) { // critical section
                    done(failed);
                }
            }
        }

        for (var i=0; i < urls.length; ++i) {
            $.ajax({
                url: urls[i],
                success: success,
                error: makeErrorHandler(urls[i])
            });
        }
    }
};
framework={
require:函数(URL,完成)
{
var剩余=url.length;
var失败=[];
//以下实现容易受到竞争条件的影响。
//好在JS通常不是多线程的。如果是,
//如果浏览器不提供某种形式的同步,
//那么,如果彼得森的算法效率低下,那么它应该能够正常工作。
函数成功(数据、文本状态、jqXHR){
如果(!--剩余){//临界截面
完成(失败);
}
}
函数makeErrorHandler(url){
返回函数(jqXHR、textStatus、errorshown){
失败。推送(url);
如果(!--剩余){//临界截面
完成(失败);
}
}
}
对于(变量i=0;i
如果您确实需要同步请求,通常可以引导底层AJAX机制来实现。例如,在jQuery中,您将
async
设置为false。使用XMLHttpRequest时,将false作为第三个参数传递给(这就是Raman在您链接到的博客文章中实现睡眠的方式)。然而,SJAX通常是一件坏事,因为它会阻止当前浏览器中的JS执行。更好的方法是使用,传递表示要运行的其余计算的函数:

framework = {
    require: function(urls, done)
    {
        function success(data, textStatus, jqXHR)
        {
            //...
        }
        function error(jqXHR, textStatus, errorThrown)
        {
            //...
        }

        urls.unshift('');
        function load() {
            urls.shift();
            if (urls.length) {
                $.ajax({
                    url: urls[0],
                    // here are some continuations
                    complete: load,
                    success: success,
                    error: error
                });
            } else {
                // here's a continuation invocation
                done();
            }
        }
    }
};
如果在加载所有给定资源时需要执行某些操作,而不是同步性,则可以对操作使用延续,但不能对资源加载使用延续。相反,您只需应用一个事件处理模型,记录每个加载的完成情况,并在所有资源请求完成时调用依赖操作

framework = {
    require: function(urls, done)
    {
        var remaining = urls.length;
        var failed=[];
        // The following implementation is vulnerable to race conditions.
        // Good thing JS isn't generally multithreaded. If (when) it is,
        // and if the browser doesn't offer some form of synchronization,
        // then Peterson's algorithm should work correctly if inefficiently.
        function success(data, textStatus, jqXHR) {
            if (!--remaining) { // critical section
                done(failed);
            }
        }
        function makeErrorHandler(url) {
            return function (jqXHR, textStatus, errorThrown) {
                failed.push(url);
                if (!--remaining) { // critical section
                    done(failed);
                }
            }
        }

        for (var i=0; i < urls.length; ++i) {
            $.ajax({
                url: urls[i],
                success: success,
                error: makeErrorHandler(urls[i])
            });
        }
    }
};
framework={
require:函数(URL,完成)
{
var剩余=url.length;
var失败=[];
//以下实现容易受到竞争条件的影响。
//好在JS通常不是多线程的。如果是,
//如果浏览器不提供某种形式的同步,
//那么,如果彼得森的算法效率低下,那么它应该能够正常工作。
函数成功(数据、文本状态、jqXHR){
如果(!--剩余){//临界截面
完成(失败);
}
}
函数makeErrorHandler(url){
返回函数(jqXHR、textStatus、errorshown){
失败。推送(url);
如果(!--剩余){//临界截面
完成(失败);
}
}
}
对于(变量i=0;i
为什么引用“laconic”?为什么引用“laconic”?实际上,您的实现对URL使用顺序而不是并行请求。所以这将是低效的。但将依赖代码放入最后一个触发的回调函数(无论我们如何检测到它是最后一个)听起来是正确而简单的解决方案。谢谢。@topright:我还以为你想要连续的请求呢。一旦加载了所需的框架,您是否实际需要执行依赖代码?我的问题是:“2并行异步c