Как заставить jQuery выполнять синхронный запрос Ajax вместо асинхронного?
У меня есть 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 ответ(ов)
Вы можете установить настройки Ajax в jQuery в синхронный режим, вызвав следующий код:
jQuery.ajaxSetup({async: false});
После этого вы можете выполнять ваши Ajax-запросы, используя jQuery.get( ... );
.
Не забудьте снова включить асинхронный режим, вызвав:
jQuery.ajaxSetup({async: true});
Я полагаю, что это работает так же, как предложено пользователем @Adam, но может быть полезно для тех, кто хочет настроить свои jQuery.get()
или jQuery.post()
на более сложный синтаксис jQuery.ajax()
.
Отличное решение! Я заметил, что когда я пытался его реализовать, если я возвращал значение в блоке успеха, оно возвращалось как 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 на странице. Хотя это может быть подходящим решением в некоторых случаях, рекомендуется использовать асинхронные вызовы и обрабатывать результаты с помощью колбеков или промисов для лучшей производительности и отзывчивости интерфейса.
Ваша функция 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
для обработки ошибок. Использование асинхронного подхода позволяет избежать блокировки интерфейса и улучшает взаимодействие с пользователем.
Я использовал ответ, данный Карчионе, и модифицировал его для работы с 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.
Конечно! Вот перевод вашего кода на русский в стиле ответа на StackOverflow:
$.ajax({
url: "test.html",
async: false
}).done(function(data) {
// Здесь можно выполнить какие-то действия с полученными данными..
}).fail(function(xhr) {
// Здесь можно обработать ошибку запроса..
});
Обратите внимание, что использование async: false
не рекомендуется, так как это может блокировать интерфейс пользователя. Рассмотрите возможность использования асинхронных запросов с обработкой результатов в колбэках.
Как загружать файлы асинхронно с помощью jQuery?
Как вернуть ответ от асинхронного вызова?
jQuery AJAX: Отправка формы
Кэширует ли Safari на iOS 6 результаты $.ajax?
Запрос Ajax возвращает 200 OK, но вместо успеха срабатывает событие ошибки