В настоящее время у меня есть эта функция:
function devuelveButaca(posicion){
var array = posicion.split('_');
var row = array[0];
var column = array[1];
var planta = $('#plantaField').val();
var resultado = "";
$.ajax({
type : 'GET',
url : 'site/numButaca',
data : {
planta : planta,
column : column,
row : row
},
success : function(data) {
if(data == 'undefined' || data == ''){
resultado = column;
}else{
resultado = data;
}
},
error : function(request, status, error) {
},
});
alert(resultado);
return resultado;
}
Который возвращает результат правильно, проблема в том, что если он не переходит в режим отладки или не ставит предупреждение перед возвратом, resultado
он возвращает пустое значение. В настоящее время предупреждение выходит пустым, но правильно возвращает результат (я использую его для добавления текста переменной в div).
Я читал, что это можно решить, установив тайм-аут, но я хотел бы знать, есть ли более элегантное решение, чем это.
Объяснение проблемы.
A в Ajax означает асинхронный; это означает, что запрос выходит за рамки обычного потока выполнения. В вашем коде ,
$.ajax
когда выполняется, следует за возвратом,return resultado
и это выполняется до того, как функция или запрос ajax передает значение ответа для успеха. Поэтому, когда вы используете предупреждение, оно возвращает пустое или неопределенное значение, поскольку сделанный вами запрос не вернулся.Возможные решения, которые вы можете дать своей проблеме:
ES2017+: промисы с async/await
Версия ECMAScript, выпущенная в 2017 году, представила поддержку асинхронных функций. С помощью async и await вы можете писать асинхронный код в синхронном стиле. Код по-прежнему будет асинхронным, но его легче читать и понимать.
Async/await основан на обещаниях, асинхронная функция всегда возвращает обещание. Ожидание берет информацию из обещания, и результатом будет значение, которое было разрешено, или ошибка, если оно было отклонено.
Вот пример того, как создать асинхронность на высоком функциональном уровне:
Использование асинхронности в функциях:
Текущие версии браузера и узла поддерживают async/await. Вы также можете поддерживать более старые среды, преобразуя свой код в ES5 с помощью регенератора (или инструментов, использующих регенератор, таких как Babel).
Текущие версии браузеров и нод поддерживают async/await. Он также поддерживается предыдущими версиями, использующими ES5 в таких инструментах, как Babel.
Использование функций обратного вызова: обратный вызов — это функция, которая будет вызываться позже, когда запрос Ajax завершится.
Пример:
Этот пример демонстрирует, что свойство
success
должно получить функцию, которую jQuery вызовет в конце запроса, если он был успешным. Кстати, есть еще один callback для управления действиями в случае ошибок. Это обрабатывается с помощью свойстваerror
; получает обратный вызов, который будет вызываться в случае неудачи.Используйте обещания:
Обещания — это контейнеры для будущих значений. Когда обещание получает значение, если оно было разрешено или отменено, оно уведомляет слушателей о том, что хочет получить доступ к этому возвращаемому значению. Одним из дополнительных преимуществ является то, что у него больше возможностей для чтения кода, и, на мой взгляд, это гораздо лучший подход. Пример:
Используйте отложенный Jquery
Это пользовательская реализация промисов, реализованная jQuery; использование очень похоже на точку, описанную выше:
Источник. Как вернуть ответ на асинхронный вызов?
одно из решений, которое вы можете сделать, — это удалить Async, чтобы получить немедленный ответ, поместив (async: false).
При совершении Ajax-вызова он выполняется асинхронно, то есть пока выполняется запрос, продолжается выполнение имеющейся у вас там функции.
Для этого у вас есть успешные и ошибочные обратные вызовы.
Если вы поместите предупреждение в Success, вы сможете увидеть результат.
Одним из решений было бы передать вашей функции обратный вызов для ее выполнения.
И вы называете это так:
Значение
resultado
возвращает пустое, потому что оно было получено через асинхронный (AJAX) вызов, но вы возвращаете его синхронно (поэтому значение еще не создано).Как вы говорите, возможным решением было бы добавить ожидание (или a
timeout
), чтобы убедиться, что значение будет получено. Но с этим могут быть проблемы: что, если значения ожидания недостаточно? Тогда у вас все равно будет та же проблема, и значение вернет null.На самом деле это неправильное использование AJAX. Идея заключается не в том, что вы что-то возвращаете (что было бы синхронно), а в том, что вы используете значения, когда получаете их асинхронно (в файле
success
).Для этого вы можете сделать две вещи:
Переместите код из того места, где вы вызываете функцию, в файл
success
. Хотя этот вариант может быть не очень хорош, если он вызывается по разным причинам или из разных функций вdevuelveButaca()
.Передайте в качестве параметра функцию обратного вызова , которая будет вызываться из файла
success
. Таким образом, вы можете звонитьdevuelveButaca()
из разных контекстов, и это всегда будет работать.