13

Как заставить jQuery выполнять синхронный запрос Ajax вместо асинхронного?

14

У меня есть JavaScript-виджет, который предоставляет стандартные точки расширения. Одна из них — функция beforecreate. Она должна возвращать false, чтобы предотвратить создание элемента.

Я добавил AJAX-вызов в эту функцию, используя jQuery:

beforecreate: function (node, targetNode, type, to) {
  jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value),
  
  function (result) {
    if (result.isOk == false) 
        alert(result.message);
  });
}

Но я хочу предотвратить создание элемента виджетом, поэтому я должен вернуть false в родительской функции, а не в коллбэке. Существует ли способ выполнить синхронный AJAX-запрос с помощью jQuery или любого другого API в браузере?

5 ответ(ов)

2

Вы можете установить настройки Ajax в jQuery в синхронный режим, вызвав следующий код:

jQuery.ajaxSetup({async: false});

После этого вы можете выполнять ваши Ajax-запросы, используя jQuery.get( ... );.

Не забудьте снова включить асинхронный режим, вызвав:

jQuery.ajaxSetup({async: true});

Я полагаю, что это работает так же, как предложено пользователем @Adam, но может быть полезно для тех, кто хочет настроить свои jQuery.get() или jQuery.post() на более сложный синтаксис jQuery.ajax().

1

Отличное решение! Я заметил, что когда я пытался его реализовать, если я возвращал значение в блоке успеха, оно возвращалось как undefined. Мне пришлось сохранить его в переменной и вернуть эту переменную. Вот метод, который я придумал:

function getWhatever() {
  // strUrl - это тот URL, который вам нужно вызвать
  var strUrl = "", strReturn = "";

  jQuery.ajax({
    url: strUrl,
    success: function(html) {
      strReturn = html;
    },
    async: false
  });

  return strReturn;
}

Обратите внимание, что использование async: false в jQuery.ajax делает запрос синхронным, что может блокировать выполнение JavaScript на странице. Хотя это может быть подходящим решением в некоторых случаях, рекомендуется использовать асинхронные вызовы и обрабатывать результаты с помощью колбеков или промисов для лучшей производительности и отзывчивости интерфейса.

0

Ваша функция getURL делает AJAX-запрос с использованием jQuery для получения данных по указанному URL. Однако, обратите внимание, что использование async: false делает запрос синхронным, что может привести к блокировке интерфейса и ухудшению пользовательского опыта. Рекомендуется использовать асинхронные запросы.

Вот пример того, как можно переписать данную функцию с использованием асинхронного подхода:

function getURL(url) {
    return $.ajax({
        type: "GET",
        url: url,
        cache: false
    });
}

// пример использования
getURL("message.php").done(function(msg) {
    alert(msg);
}).fail(function(jqXHR, textStatus, errorThrown) {
    console.error("Ошибка запроса: " + textStatus, errorThrown);
});

В этом примере getURL возвращает Promise, благодаря чему вы можете использовать done для обработки успешного результата и fail для обработки ошибок. Использование асинхронного подхода позволяет избежать блокировки интерфейса и улучшает взаимодействие с пользователем.

0

Я использовал ответ, данный Карчионе, и модифицировал его для работы с JSON.

function getUrlJsonSync(url) {
    var jqxhr = $.ajax({
        type: "GET",
        url: url,
        dataType: 'json',
        cache: false,
        async: false
    });

    // 'async' должен быть 'false', чтобы это работало
    var response = { valid: jqxhr.statusText, data: jqxhr.responseJSON };

    return response;
}    

function testGetUrlJsonSync() {
    var reply = getUrlJsonSync("myurl");

    if (reply.valid == 'OK') {
        console.dir(reply.data);
    } else {
        alert('невалидный ответ');
    }    
}

Я добавил dataType со значением 'JSON' и изменил .responseText на responseJSON.

Также я получил статус, используя свойство statusText возвращаемого объекта. Обратите внимание, что это статус Ajax-ответа, а не признак валидности JSON.

На сервере необходимо возвращать ответ в правильном (корректно сформированном) формате JSON, иначе возвращаемый объект будет неопределенным.

Есть два аспекта, которые следует учитывать при ответе на оригинальный вопрос. Первый — это указание Ajax выполнять запрос синхронно (установив async: false), а второй — возврат ответа через оператор return в вызывающей функции, а не через колбэк-функцию.

Я также попробовал использовать POST, и это сработало.

Я изменил GET на POST и добавил data: postdata:

function postUrlJsonSync(url, postdata) {
    var jqxhr = $.ajax({
        type: "POST",
        url: url,
        data: postdata,
        dataType: 'json',
        cache: false,
        async: false
    });

    // 'async' должен быть 'false', чтобы это работало
    var response = { valid: jqxhr.statusText, data: jqxhr.responseJSON };

    return response;
}

Обратите внимание, что приведенный выше код работает только в случае, когда async установлен в false. Если вы установите async: true, возвращаемый объект jqxhr не будет валидным в момент возврата AJAX-вызова, а только позже, когда асинхронный вызов завершится, но в этот момент будет уже слишком поздно для установки переменной response.

0

Конечно! Вот перевод вашего кода на русский в стиле ответа на StackOverflow:

$.ajax({
  url: "test.html",
  async: false
}).done(function(data) {
   // Здесь можно выполнить какие-то действия с полученными данными..
}).fail(function(xhr) {
   // Здесь можно обработать ошибку запроса..
});

Обратите внимание, что использование async: false не рекомендуется, так как это может блокировать интерфейс пользователя. Рассмотрите возможность использования асинхронных запросов с обработкой результатов в колбэках.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь