Tengo un widget de JavaScript que proporciona puntos de extensión estándar. Uno de ellos es la beforecreate
función. Debería volver false
para evitar que se cree un elemento.
Agregué una llamada Ajax a esta función usando 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);
});
}
Pero quiero evitar que mi widget cree el elemento, por lo que debería regresar false
en la función madre, no en la devolución de llamada. ¿Hay alguna manera de realizar una solicitud AJAX sincrónica usando jQuery o cualquier otra API en el navegador?
javascript
jquery
ajax
asynchronous
Artem Tikhomirov
fuente
fuente
beforecreate
.Respuestas:
De la documentación de jQuery : usted especifica que la opción asíncrona sea falsa para obtener una solicitud de Ajax sincrónica. Luego, su devolución de llamada puede establecer algunos datos antes de que su función madre continúe.
Así es como se vería su código si se modifica como se sugiere:
fuente
async: false
todavía es compatible con jQuery> = 1.8. La capacidad de usarasync: false
con jqXHR ($.Deferred
) es lo que fue desaprobado. En otras palabras, hay que utilizar las nuevas opciones de error / éxito / completos de devolución de llamada, en lugar de los métodos heredados, por ejemplo,jqXHR.done()
.Puede poner la configuración de Ajax de jQuery en modo síncrono llamando
Y luego realice sus llamadas Ajax usando
jQuery.get( ... );
Luego, solo enciéndelo una vez
Supongo que funciona de la misma manera sugerida por @Adam, pero podría ser útil para alguien que quiera reconfigurar su
jQuery.get()
ojQuery.post()
lajQuery.ajax()
sintaxis más elaborada .fuente
$.ajax()
". ;)Excelente solucion! Cuando intenté implementarlo, noté que si devolvía un valor en la cláusula de éxito, volvía a estar indefinido. Tuve que almacenarlo en una variable y devolver esa variable. Este es el método que se me ocurrió:
fuente
getWhatever
. Por lo tanto no devolvió nada, es decir,undefined
de sugetWhatever
.Todas estas respuestas pierden el punto de que hacer una llamada Ajax con async: false hará que el navegador se cuelgue hasta que se complete la solicitud de Ajax. El uso de una biblioteca de control de flujo resolverá este problema sin colgar el navegador. Aquí hay un ejemplo con Frame.js :
fuente
fuente
getURL
vsget
? ¿Por qué uno cuelga mi navegador?" etc.Nota: No debe usar
async: false
debido a estos mensajes de advertencia:Chrome incluso advierte sobre esto en la consola:
Esto podría romper su página si está haciendo algo como esto, ya que podría dejar de funcionar cualquier día.
Si desea hacerlo de una manera que todavía se siente como si fuera síncrono pero aún no se bloquea, entonces debe usar async / wait y probablemente también algo de ajax que se base en promesas como la nueva API Fetch
Editar Chrome está trabajando en No permitir sincronización XHR en el cierre de página cuando el usuario está navegando o cerrando la página. Esto implica antes de descargar, descargar, ocultar páginas y cambiar la visibilidad.
si este es su caso de uso a continuación, es posible que desee echar un vistazo a navigator.sendBeacon vez
También es posible que la página deshabilite la solicitud de sincronización con los encabezados http o el atributo allow del iframe
fuente
await fetch(url)
llamada en untry... catch
bloque para detectar cualquier error asincrónico.async
al principio, por lo que podría hacerfoo().catch(...)
para atraparla tambiénbeforeunload
pero luego revirtió el cambio después de comentarios negativos bch.chromium.org/p/chromium/issues/detail?id=952452Tenga en cuenta que si está haciendo una llamada Ajax entre dominios (utilizando JSONP ), no puede hacerlo de forma sincrónica,
async
jQuery ignorará el indicador.Para llamadas JSONP puede usar:
fuente
Con
async: false
usted consigue un navegador bloqueado. Para una solución síncrona sin bloqueo, puede usar lo siguiente:ES6 / ECMAScript2015
Con ES6 puede usar un generador y la biblioteca de co :
ES7
Con ES7 puedes usar asyc await:
fuente
async function
a beforecreatebeforecreate: async function(....
y eliminar la función asincrónica auto invocadaUsé la respuesta dada por Carcione y la modifiqué para usar JSON.
He añadido el tipo de datos de 'JSON' y cambió el .responseText a responseJSON .
También recuperé el estado usando la propiedad statusText del objeto devuelto. Tenga en cuenta que este es el estado de la respuesta de Ajax, no si el JSON es válido.
El back-end tiene que devolver la respuesta en JSON correcto (bien formado), de lo contrario el objeto devuelto será indefinido.
Hay dos aspectos a considerar al responder la pregunta original. Uno le está diciendo a Ajax que funcione sincrónicamente (configurando async: false ) y el otro le devuelve la respuesta a través de la declaración return de la función de llamada, en lugar de hacerlo en una función de devolución de llamada.
También lo probé con POST y funcionó.
Cambié GET a POST y agregué datos: postdata
Tenga en cuenta que el código anterior solo funciona en el caso de que async sea falso . Si estableciera async: true, el objeto devuelto jqxhr no sería válido en el momento en que regrese la llamada AJAX, solo más tarde cuando la llamada asincrónica haya finalizado, pero eso es demasiado tarde para establecer la variable de respuesta .
fuente
Este es un ejemplo:
fuente
async false
con una solución basada en promesas? Esto solo bloquea el navegador sin ningún beneficio.ajax
llamadas ya regresan) y.then()
odone()
(como ya se muestra). Bloquear el navegador es una experiencia de usuario muy pobre. Como dije tenerasync: false
en este ejemplo es una completa pérdida de tiempo.En primer lugar, debemos entender cuándo usamos $ .ajax y cuándo usamos $ .get / $. Post
Cuando requerimos un control de bajo nivel sobre la solicitud ajax, como la configuración del encabezado de la solicitud, la configuración de almacenamiento en caché, la configuración síncrona, etc., entonces deberíamos ir por $ .ajax.
$ .get / $. post: cuando no requerimos un control de bajo nivel sobre la solicitud de ajax. Simplemente obtenga / publique los datos en el servidor. Es una abreviatura de
y, por lo tanto, no podemos usar otras funciones (sincronización, caché, etc.) con $ .get / $. post.
Por lo tanto, para el control de bajo nivel (sincronización, caché, etc.) sobre la solicitud ajax, deberíamos ir por $ .ajax
fuente
Esta es mi implementación simple para solicitudes ASYNC con jQuery. Espero que esto ayude a cualquiera.
fuente
Debido a que
XMLHttpReponse
la operación síncrona está en desuso, se me ocurrió la siguiente solución que se ajustaXMLHttpRequest
. Esto permite consultas AJAX ordenadas sin dejar de ser asincrónico, lo cual es muy útil para los tokens CSRF de un solo uso.También es transparente, por lo que las bibliotecas como jQuery funcionarán sin problemas.
fuente
Dado que la pregunta original era sobre
jQuery.get
, vale la pena mencionar aquí que (como se mencionó aquí ) se podría usarasync: false
de una manera ideal,$.get()
pero evitarlo ya que el asíncronoXMLHTTPRequest
está en desuso (y el navegador puede dar una advertencia):fuente
Establecer
asyn:false
en la solicitud ajax para hacerlo sincrónico.Aquí está el ejemplo de código:
Esto puede hacer que la pantalla no responda.
fuente