una tipos sincronas programacion peticiones pasar parametros pagina funciones funcion ejecutar desde cargar asincronia asincrona antes javascript ajax asynchronous

tipos - programacion asincrona javascript



Devuelve el valor de la funciĆ³n con una llamada Ajax (2)

Esta pregunta ya tiene una respuesta aquí:

¿Puede alguien decirme cómo devolver el valor del status como el valor de retorno de la función?

function checkUser() { var request; var status = false; //create xmlhttprequest object here [called request] var stu_id = document.getElementById("stu_id").value; var dName = document.getElementById("dName").value; var fileName = "check_user.php?dName=" + dName + "&stu_id=" + stu_id; request.open("GET", fileName, true); request.send(null); request.onreadystatechange = function() { if (request.readyState == 4) { var resp = parseInt(request.responseText, 10); if(resp === 1) { alert("The display name has already been taken."); status = false; } else if(resp === 2) { alert("This student ID has already been registered"); status = false; } else if(resp === 0) { status = true; } } } return status; }

La función anterior se activa cuando presiona enviar en un formulario de registro (como debe ser obvio). El problema es que este formulario se envía independientemente de cuál sea la respuesta, y el cuadro de alerta a veces no muestra nada [en blanco], a veces no se muestra en absoluto. Sin embargo, si cambio el status final a false manualmente [es decir, reemplazo el status por false ], se muestra el valor correcto en el cuadro de alerta.

PD: soy peor que un novato en JavaScript, por lo que también se agradecen las sugerencias para mejorar el código en general.


Es posible ejecutar el método de envío de forma síncrona, por lo que request.responseText estará disponible de inmediato, pero normalmente no es una buena idea. La solicitud colgará el navegador hasta que esté completo.

Para establecer la solicitud como sincrónica, configure el tercer parámetro como request.open en "falso".

function checkUser() { var request; var status = false; //create xmlhttprequest object here [called request] var stu_id = document.getElementById("stu_id").value; var dName = document.getElementById("dName").value; var fileName = "check_user.php?dName=" + dName + "&stu_id=" + stu_id; request.open("GET", fileName, false); request.send(null); if (request.status === 200) { var resp = parseInt(request.responseText, 10); if(resp === 1) { alert("The display name has already been taken."); status = false; } else if(resp === 2) { alert("This student ID has already been registered"); status = false; } else if(resp === 0) { status = true; } } else { alert("Request failed"); status = false; } return status; }

Como mencioné antes, esta no es una buena idea . Casi siempre es una mejor idea realizar la solicitud de forma asíncrona para que se pueda ejecutar otro código mientras espera una respuesta. Hay una razón por la cual A jax atrapó en lugar de S jax.


El problema es que onreadystatechange no se disparará hasta ... espere ... el estado cambia. Entonces, cuando return status; la mayoría de las veces el estado no tendrá tiempo para establecerse. Lo que debes hacer es return false; siempre y dentro de onreadystatechange determinan si desea continuar o no. Si lo hace, envíe el formulario. En resumen, tome el código que maneja el valor de retorno y en su lugar ejecútelo desde el controlador readystatechange. Puedes hacer esto directamente:

request.onreadystatechange = function() { if (request.readyState == 4) { var resp = parseInt(request.responseText, 10); switch (resp) { case 0: document.getElementById(''myform'').submit(); break; case 1: alert("The display name has already been taken."); break; case 2: alert("This student ID has already been registered"); break; } } } return false; // always return false initially

o pasando una continuación a la función que realiza la llamada asincrónica:

function checkUser(success, fail) { ... request.onreadystatechange = function() { if (request.readyState == 4) { var resp = parseInt(request.responseText, 10); switch (resp) { case 0: success(request.responseText); case 1: fail("The display name has already been taken.", request.reponseText); break; case 2: fail("This student ID has already been registered", request.reponseText); break; default: fail("Unrecognized resonse: "+resp, request.reponseText); break; } } }

Además de esto, antes de la return false; predeterminada, es return false; Es posible que desee tener algún tipo de indicador de que algo está sucediendo, quizás deshabilite el campo de envío, muestre un círculo de carga, etc. De lo contrario, los usuarios podrían confundirse si tarda mucho tiempo en obtener los datos.

Explicación adicional

Muy bien, entonces la razón por la que tu camino no funcionó es principalmente en esta línea:

request.onreadystatechange = function() {

Lo que está haciendo es decir que cuando el onreadystatechange de onreadystatechange de onreadystatechange de AJAX cambie, se ejecutará la función anónima que está definiendo. Este código NO se está ejecutando de inmediato. Está esperando que ocurra un evento. Este es un proceso asíncrono, por lo que al final de la definición de la función, javascript continuará y si el estado no ha cambiado para cuando return status; el status la variable obviamente no habrá tenido tiempo para establecerse y su script no funcionaría como se esperaba. La solución en este caso es siempre return false; y luego, cuando se dispara el evento (es decir, el servidor respondió con el resultado del script de PHP), puede determinar el estado y enviar el formulario si todo está bien.