Condiciones de carrera de Ajax

8

¿Existe un patrón o una forma estándar de manejar las condiciones de carrera de Ajax? Toma el siguiente ejemplo. Tienes dos mesas. Al hacer clic en una fila de la tabla 1, se eliminan los datos de la base de datos y luego se actualiza la tabla 2 (que ahora mostraría todas las filas de la tabla 1 menos la fila en la que se hizo clic).

Si alguien hace clic en un montón de filas en una sucesión rápida, podría obtener un escenario en el que la tabla 2 no se actualiza para todos los clics que se hacen para problemas de tiempo / retraso.

¿Cuál podría ser una buena manera de abordar esto? Estaba pensando en usar una posible cola, pero ese tipo de derrota el propósito de hacerlo de forma asincrónica. Sin embargo, aún tendría el beneficio de que la interfaz de usuario no se bloquea.

Ominus
fuente
AJAX y bases de datos? ¿Cómo se unen los dos en esto?
Finalizado
Sí, era un poco vago. Es una aplicación web con datos que se envían / ​​recuperan a través de ajax, más específicamente jQuery.get / post.
Ominus

Respuestas:

8

Solo un pensamiento, quizás podría crear una lista para sus métodos de devolución de llamada Ajax. Envolvería su devolución de llamada real de Ajax en un método que agrega esa devolución de llamada a una ranura en una lista.

Esta lista espera devoluciones de llamada en un orden específico y solo se ejecuta si se llena el elemento superior (la devolución de llamada que desea llamar primero).

Greg
fuente
1
Anidar mediante programación las devoluciones de llamada es una solución sólida.
Sam
7

Esta no es una condición de carrera.

Se produciría una condición de carrera cuando el comportamiento entre dos subprocesos asincrónicos se vuelve indefinido. Puede resolver este problema anidando la devolución de llamada desde la primera llamada

Sam
fuente
66
No todas las llamadas AJAX se completarán a la misma velocidad debido a posibles problemas de red. Lo vemos incluso en desarrollo en nuestra red local, donde una llamada AJAX posterior finalizará antes que una anterior, y la IU termina mal. Las devoluciones de llamadas anidadas / en cola lo resolverán, pero esta es una condición de carrera.
Izkata
1
@Izkata Esto es incorrecto, Javascript no tiene condiciones de carrera porque se ejecuta en un solo hilo. La situación que está describiendo es similar a ejecutar dos funciones al mismo tiempo, una para abrir un archivo y otra para leer el contenido del archivo abierto. La función de abrir archivo debe ejecutarse antes que la función de lectura, pero ejecutar ambas al mismo tiempo significa que a veces la segunda función se ejecutará primero. Esta no es una condición de carrera, está fallando en ordenar las cosas correctamente. La respuesta correcta para Javascript en 2017 es utilizar Promise.then()para ejecutar devoluciones de llamada asíncronas en el orden correcto.
Daniel T.
1
@Izkata No es una condición de carrera, es un problema de pedido. El navegador maneja la solicitud de forma nativa, pero la devolución de llamada se ejecuta en el hilo JS. Las condiciones de carrera se producen cuando dos subprocesos que se ejecutan simultáneamente comparten el mismo recurso y leen / escriben en el recurso al mismo tiempo, lo que conduce a una salida no determinista. Si tiene dos solicitudes AJAX simultáneas, la salida es determinista; es el resultado de la devolución de llamada A o la devolución de llamada B. Lo que no sabe es el orden en que se invocarán las devoluciones de llamada. Esto no es diferente a proporcionar dos botones para el usuario y
Daniel T.
1
sin saber en qué botón hará clic el usuario primero. El resultado será la devolución de llamada para el botón A o la devolución de llamada para el botón B, pero nunca una salida impredecible y no determinista. Si necesita controlar el orden en que se invocan las devoluciones de llamada, debe usar promesas. Pero el tiempo de invocación de devolución de llamada impredecible no es lo mismo que las condiciones de carrera.
Daniel T.
1
@Izkata Un 'resultado inesperado' en una condición de carrera significa que una función no es determinista, algo que no sucede en JS debido exactamente a lo que dijo: "cuando cualquier comportamiento concurrente puede causar un resultado inesperado". La palabra clave aquí es concurrente; Las solicitudes AJAX son concurrentes, las devoluciones de llamada no lo son. Por lo tanto, el resultado de las funciones de devolución de llamada en JS siempre es determinista porque se ejecutan secuencialmente, nunca simultáneamente. Esta publicación es una buena lectura: blog.raananweber.com/2015/06/17/…
Daniel T.
6

En general, las devoluciones de llamada son una herramienta universal para tratar tareas asincrónicas y, de hecho, las devoluciones de llamada son el mecanismo para manejar las solicitudes AJAX en JavaScript. En el contexto de la devolución de llamada, incluso puede tener referencia a la fila en la que se hace clic (si está cerrada en el cierre). Puede encontrar útiles los siguientes artículos: jQuery diferido y Uso de diferidos en jQuery

Otra cosa que debe tener en cuenta, si el usuario puede hacer clic en varios botones, es que se iniciarán varias solicitudes. Sin embargo, diferentes navegadores pueden manejar diferentes cantidades de solicitudes AJAX simultáneamente: concurrent-ajax-xmlhttprequest-request . Para superar esto, debe implementar alguna cola de solicitud básica.

rusev
fuente
+1 por ser el único que habla de cosas diferidas.
Florian Margaine