Estoy escribiendo un código donde habrá una función (doAjax) para manejar todas las solicitudes de diferentes funcionalidades. Esto funciona bien cuando se usa en el sentido normal (hacer clic en los botones, etc.), pero estoy tratando de llamar a algunas cosas cuando se carga la página para inicializar el estado de la aplicación.
Aquí está la función Ajax:
function doAjax(type, action, data = null){ return new Promise(function(res,rej){ xhr = new XMLHttpRequest(); xhr.open(type, '/inc/functions.php?action='+action, true); xhr.timeout = 20000; xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.onload = function() { if (this.status === 200) { res(xhr); } else { console.log("some xhr error occured"); rej("some xhr error happened"); } }; xhr.send(data); }); }Y aquí hay un par de ejemplos de funciones que envían solicitudes a esto:
/* get file structure of files */ function buildTree(){ doAjax('GET', 'get_files').then(r => { var res = JSON.parse(r.response); console.log(res); /* the json is processed here and stuff is displayed on the front end */ } } /* get user data from database */ function populateShare(){ doAjax('GET', 'social_populate').then(r => { var res = JSON.parse(r.response); console.log(res); /* again, the json received from the database is processed and output to the front end */ } }¡También debo mencionar que estas funciones también están vinculadas a los oyentes de clics, por lo que se usan en la aplicación más adelante y en la carga!
Ahora, el problema es cuando trato de ejecutar ambos en la carga de la página como una especie de función de inicialización (para configurar la aplicación lista para usar). Si ejecuto lo siguiente:
function init(){ buildTree(); populateShare(); } init(); //called laterAmbos console.logs generan el mismo resultado: el retorno de social_populate (llamado desde populateShare()).
Entonces, mi pregunta en última instancia es si hay alguna forma de poner en cola las llamadas de función en la función init(), esperando que cada una termine antes de pasar a la siguiente. Puede haber más funciones que deban llamarse en init(), algunas también involucran solicitudes Ajax.
He intentado lo siguiente, encontrado en otro hilo, pero desafortunadamente devuelve el mismo resultado:
async function initialise(){ try { const p1 = buildTree(); const p2 = populateShare(); await Promise.all([p1, p2]); } catch (e) { console.log(e); } }Sé que podría cargar todo el lote desde el back-end y devolverlo en un JSON enorme, ¡pero tengo más curiosidad por saber si se puede lograr lo anterior! Siento que he entrado en algún tipo de ciclo de muerte de solicitud síncrona, ¡o me estoy perdiendo algo descaradamente obvio aquí!
¡Además, no jQuery por favor!
¡Gracias!
Parecía haber usado accidentalmente una variable global cuando declaraba xhr , que se sobrescribía en cada llamada.
Prueba let xhr = new XMLHttpRequest();