问题
I have a couple of jQuery Ajax requests, which have to be synchronous, but they keep locking/freezing the browser, until the response is received. My main problem is, that until the response is received I have to display a spinning icon, but due to the freezing the spinner is not displayed and even if it miraculously is it doesn't animate.
This is the event displaying the spinner and sending the request:
$(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
}
});
The request:
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;
}
Until the request returns the received JSON data, everything stops moving. How can I fix this please?
回答1:
That's the essence of synchronous requests, they are locking. You may want to try to move the requests to a web worker. Here's an example (not using XHR, but it can give you an implementation idea)
A web worker is implemented in a separate file, the scripting can look like:
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});
}
});
}
回答2:
Depending on your use case you can use something like
task.js Simplified interface for getting CPU intensive code to run on all cores (node.js, and web)
A example would be
// 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
});
You should not be doing this though, unless you need to do some heavy data processing, please use async requests.
来源:https://stackoverflow.com/questions/26503620/synchronous-ajax-requests-lock-browser