¿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.

  • localization y JQuery / JavaScript
  • Convirtiendo SVG creado con D3js a PNG
  • jquery cambiar el tamaño en el elemento div
  • jquery ui out: la function no se activa
  • Compartir datos entre páginas html
  • Cómo establecer dinámicamente estado marcado en el button de opción en Angular js
  • ¿Cómo generar un pdf desde la página web html?
  • Variable global de javascript dentro de document.ready
  • ¿Cómo selecciono todo el text contenido en <pre> usando jQuery?
  • ¿Cómo get evento de prensa larga en js angulares?
  • ¿Cómo comunicarse entre los modules de JavaScript ...?
  • Javascript tiene muchos buenos JS marco (como Node.js AngularJS Vue.js React.js) es el mejor lenguaje de script.