Synchronous Ajax requests “lock” browser

不问归期 提交于 2019-12-08 11:33:45

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!