¿Por qué mi variable permanece sin cambios después de modificarla dentro de una función?

Este es un problema común al trabajar con código asíncrono en JavaScript. Muchos desarrolladores se encuentran confundidos cuando una variable global parece no actualizar su valor, incluso después de que se ha intentado modificarla dentro de una función. Analicemos por qué esto sucede a través de algunos ejemplos.

Ejemplo 1: Cargando una imagen

var outerScopeVar;

var img = document.createElement('img');
img.onload = function() {
    outerScopeVar = this.width;
};
img.src = "https://stackoverflow.com/questions/79528992/lolcat.png";
alert(outerScopeVar);

En este caso, la variable outerScopeVar se establece dentro de una función que se ejecuta cuando la imagen ha terminado de cargarse. Sin embargo, el alert se ejecuta antes de que la imagen haya terminado de cargar, por lo que muestra undefined.

Ejemplo 2: Usando setTimeout

var outerScopeVar;
setTimeout(function() {
    outerScopeVar = "¡Hola Mundo Asincrónico!";
}, 0);
alert(outerScopeVar);

Aquí, la función del setTimeout se ejecuta de manera asíncrona después de que se completa el ciclo de eventos actual. Por lo tanto, el alert anterior sigue mostrando undefined.

Ejemplo 3: Uso de jQuery

var outerScopeVar;
$.post('loldog', function(response) {
    outerScopeVar = response;
});
alert(outerScopeVar);

En este ejemplo, el código dentro de la función de jQuery se ejecuta una vez que se recibe la respuesta de la solicitud. Sin embargo, el alert se activa antes de que ocurra la respuesta, resultando nuevamente en undefined.

Ejemplo 4: Lectura de archivos en Node.js

var outerScopeVar;
fs.readFile('./catdog.html', function(err, data) {
    outerScopeVar = data;
});
console.log(outerScopeVar);

Similar a los ejemplos anteriores, la función que establece outerScopeVar se ejecuta de manera asíncrona después de que se lee el archivo, dejando a console.log mostrando undefined.

Ejemplo 5: Uso de Promesas

var outerScopeVar;
myPromise.then(function (response) {
    outerScopeVar = response;
});
console.log(outerScopeVar);

En las promesas, el resultado se maneja de forma asíncrona. El console.log mostrará undefined si se ejecuta antes de que la promesa se resuelva.

Ejemplo 6: Uso de Observables

var outerScopeVar;
myObservable.subscribe(function (value) {
    outerScopeVar = value;
});
console.log(outerScopeVar);

El comportamiento es similar al de las promesas. El subscribe actúa de manera asíncrona, lo que significa que el console.log mostrará undefined inicialmente.

Ejemplo 7: API de Geolocalización

var outerScopeVar;
navigator.geolocation.getCurrentPosition(function (pos) {
    outerScopeVar = pos;
});
console.log(outerScopeVar);

Finalmente, al igual que en los ejemplos anteriores, el resultado de la geolocalización se obtiene de manera asíncrona. Como resultado, console.log muestra undefined.

Conclusión

Todos estos ejemplos comparten un patrón común: el código que modifica la variable se ejecuta de manera asíncrona, lo que significa que el código que intenta acceder a dicha variable se está ejecutando antes de que se produzca la actualización. Este comportamiento está intrínsecamente ligado a la naturaleza del trabajo asíncrono en JavaScript. Para gestionar correctamente este tipo de situaciones, es fundamental emplear técnicas apropiadas como callbacks, promesas o async/await para asegurar que el valor se obtenga después de que la operación asíncrona se complete.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *