¿Es esto un problema de scope en JavaScript / JQuery?

Posible duplicado:
¿Es posible usar ajax respone fuera de él?

Creé la siguiente rutina de JavaScript que va a un service WCF oData y obtiene algunos datos. En el elemento de éxito, obtengo los resultados en la variable de resultados y los alerta – Veo que hay objects devueltos. Cuando ejecuto la segunda alerta, fuera de la llamada ajax y antes de devolver los resultados, la variable de resultados está "indefinida".

¿Puede alguien decirme por favor dónde me estoy equivocando?

function retrieveJsonpODataSet(baseUrl, query) { var oDataUrl = baseUrl + "?$format=json&$callback=?"; var results; $.ajax( { url: oDataUrl, contentType: 'application/json; charset=utf-8', type: 'GET', dataType: 'jsonp', async: false, success: function (data, textStatus, xhr) { results = data.d; alert(results); // This shows the results }, error: function (xhr, textStatus, errorThrown) { alert("Query failed.\n\n" + oDataUrl + "\n\n" + errorThrown); results = null; } }); alert(results); // This shows "undefined" return results; } 

Por favor, ignore el parámetro de consulta: todavía no he terminado la rutina.

EDITAR

Inicialmente no tenía async:false en la llamada ajax. He agregado eso ahora pero no soluciona el problema.

4 Solutions collect form web for “¿Es esto un problema de scope en JavaScript / JQuery?”

La llamada ajax es una operación asincrónica. Dispara y tu código no se detiene. De modo que se devuelven los results que en ese punto no están definidos. Lo que debe hacer es pasar la callback a la function.

 function retrieveJsonpODataSet(baseUrl, query, callback) { /* some code */ $.ajax({ /* some settings */ success: function(res) { /* some code */ callback(results); } }); } 

Ahora lo usas así

 retrieveJsonpODataSet(baseUrl, query, function(res) { /* Hurray, I have result now in res variable! */ }); 

NO USE async: false ¡ OPCIÓN FALTA ! Bloquea TODOS los scripts hasta que finaliza la llamada … ¿y si no termina? Serás bloqueado para siempre

EDITAR

Me he perdido que la request es JSONP. En ese caso, async: false ni siquiera funcionará (no funciona para requestes entre dominios y JSONP). Entonces, debes usar devoluciones de llamada de todos modos.

¡Un compañero Richard!

Esto no es un problema de scope, sino más bien de ejecución. Las opciones de success y error son controlleres de events y se ejecutan de forma asincrónica (de ahí que se denomine AJAX). Esto significa esencialmente que la alert(results) y los return results pueden, y probablemente serán, ejecutados antes de que se desencadenen los events de success o error .

Tu ajax es asynchronous, por lo que la alerta se ejecuta antes de que se complete el ajax. Debe establecer la propiedad async de la llamada ajax en false para que la secuencia de commands detenga la ejecución hasta que se realice y procese la request ajax.

Sin embargo, jQuery documentos dice:

async Valor pnetworkingeterminado: true De forma pnetworkingeterminada, todas las requestes se envían de forma asíncrona (es decir, se establece de forma pnetworkingeterminada en true). Si necesita requestes sincrónicas, establezca esta opción en falso. Solicitudes entre dominios y tipo de datos: las requestes "jsonp" no son compatibles con la operación síncrona. Tenga en count que las requestes sincrónicas pueden bloquear temporalmente el browser, deshabilitando cualquier acción mientras la request está activa. A partir de jQuery 1.8, el uso de async: false está en desuso.

Se envía una request AJAX, sin que el script esté esperando una respuesta, eso es lo que Dave Newton quiere decir con A-synchronus , coloca la alerta dentro de la function de callback exitosa y verás cuál es la respuesta real.

alternativamente, puede especificar la propiedad async y establecerla en false para forzar a su script a esperar la respuesta, antes de continuar.

  • cómo usar jquery get elemento seleccionado tiene modo MÚLTIPLE e invertir
  • ¿Cómo cambio el estilo del cursor con JQuery?
  • Convierta json en una cadena usando jquery
  • - Sepa si div ya tiene tooltipster
  • Javascript Alertify con devolución de confirmar
  • La function JQuery Unique () no funciona correctamente
  • ¿Debería agregar HTML al DOM usando innerHTML o creando nuevos elementos uno por uno?
  • use jquery para seleccionar una opción desplegable
  • Javascript tiene muchos buenos JS marco (como Node.js AngularJS Vue.js React.js) es el mejor lenguaje de script.