2014-10-22 184 views
0

我有几个jQuery Ajax请求,它们必须是同步的,但它们会一直锁定/冻结浏览器,直到收到响应。我的主要问题是,直到收到响应,我必须显示一个旋转图标,但由于冻结,微调不显示,即使它奇迹般地不动画。同步Ajax请求“锁定”浏览器

这是显示旋转器和发送该请求的事件:

$(document).on('click', '#open-button', function() { 

    var input = "some text"; 
    var wrapper = $('#wrapperWindow'); 
    wrapper.children().animate({ 
     opacity: 0 
    }, 500); 
    wrapper.children().remove(); 
    wrapper.append('<div id="loading-spinner" style="display:none;"></div>'); 
    var spinner = $('#loading-spinner'); 
    spinner.css({ 
     backgroundImage: 'url("img/loading.gif")', 
     opacity: 0 
    }); 
    spinner.show(); 
    spinner.animate({ 
     opacity: 1 
    }, 500); 

    var dataForTab = requestData(input); //<-- the request 

    if (dataForTab.length > 0) { 
     //do stuff 
    } 

}); 

请求:

function requestData(input) { 

    var result = null; 

    $.ajax({ 
     async: false, 
     type: "POST", 
     url: "/some/url?input=" + input, 
     dataType: "json", 
     retryLimit: 3, 

     success: function (json) { 
      result = json; 
     }, 

     error: function (xhr, err) { 
      console.log(xhr); 
      console.log(err); 
     } 
    }); 

    return result; 
} 

直到请求返回所接收的JSON数据,一切都停止移动。我该如何解决这个问题?

+6

你不能....修复它的方法是使用异步处理 – 2014-10-22 08:52:55

+0

看看 - http://stackoverflow.com/questions/14220321/how-to-return-the-response- from-an-ajax-call – 2014-10-22 08:53:30

+2

[$ .ajax().async](http://api.jquery.com/jQuery.ajax/) - *请注意,同步请求可能会临时锁定浏览器,禁用任何操作请求已激活* – 2014-10-22 08:54:14

回答

4

这是同步请求的本质,它们是锁定的。您可能想尝试将请求移至web worker。下面是一个example(不使用XHR,但它可以给你一个实现想法)

网络工作者在一个单独的文件中实现,该脚本可以看起来像:

onmessage = function (e) { 
var result = null; 

    $.ajax({ 
     async: false, 
     type: "POST", 
     url: "/some/url?input=" + input, 
     dataType: "json", 
     retryLimit: 3, 

     success: function (json) { 
      result = json; 
      postMessage({result: result}); 
     }, 

     error: function (xhr, err) { 
      postMessage({error: err}); 
     } 
    }); 

} 
+0

我只是通读它而已。看起来这可能是一个解决方案。谢谢! – Dropout 2014-10-22 08:59:03

+0

我可以将工作人员实施为匿名功能吗?你知道..像'新工人(函数(){...});' – Dropout 2014-10-22 09:08:47

+0

答案:http://stackoverflow.com/questions/5408406/web-workers-without-a-separate-javascript-file – Dropout 2014-10-22 09:16:51

0

根据您的使用情况,你可以使用类似于

task.js简化的接口来获取CPU密集型代码在所有内核上运行(node.js的,和网络)

一个例子是

// turn blocking pure function into a worker task 
const syncWorkerRequest = task.wrap(function (url) { 
    // sync request logic 
}); 

// run task on a autoscaling worker pool 
syncWorkerRequest('./bla').then(result => { 
    // do something with result 
}); 

你不应该执行该操作,除非你需要做一些繁重的数据处理,请使用异步请求。