Asincronía problema en Electron

Actualmente estoy trabajando en una aplicación Electron.js y tengo un problema de asincronía. Tengo tres funciones (downdloadFile ()) dentro de tres sentencias if que deben ejecutarse en secuencia pero se ejecutan de forma asíncrona; Ya intenté usar async / await pero no funcionó. Aquí está mi código:

ipcMain.on('play',(event,payload) => { launcherConfig.savedRam = payload.savedRam; launcherConfig.savedMaxPermSize = payload.savedMaxPermSize; if(payload.selectedPacket) { //FIRST IF if (!fs.existsSync(launcherDir + "\\natives")) { downloadFile("http://soulnetwork.it/launcher/natives.zip", launcherDir + "\\natives.zip", true, 'natives'); } //SECOND IF if (!fs.existsSync(launcherDir + "\\bin")) { downloadFile("http://soulnetwork.it/launcher/bin.zip", launcherDir + "\\bin.zip", true, 'bin'); } //THIRD IF if (launcherConfig.installed_modpacks.includes(payload.selectedPacket)) { launchMinecraft(payload.selectedPacket); saveConfig(); } else { downloadFile(`http://soulnetwork.it/launcher/modpacks/${payload.selectedPacket}.zip`, launcherDir + "\\modpacks\\" + payload.selectedPacket + '.zip', true, payload.selectedPacket, launchMinecraft); launcherConfig.installed_modpacks.push(payload.selectedPacket); saveConfig(); } } } function downloadFile(file_url , targetPath, showProcess, packetName, callback){ // Save variable to know progress var received_bytes = 0; var total_bytes = 0; var req = request({ method: 'GET', uri: file_url }); var progressWindow = null; if(showProcess){ progressWindow = new BrowserWindow({width: 300, height: 60, title: `Downloading ${packetName}`,icon: '../public/images/sn.png'}) progressWindow.setProgressBar(0.0); progressWindow.loadURL('file://' + __dirname + '/views/download.ejs'); progressWindow.setMenu(null); } var out = fs.createWriteStream(targetPath); req.pipe(out); req.on('response', function ( data ) { // Change the total bytes value to get progress later. total_bytes = parseInt(data.headers['content-length' ]); }); req.on('data', function(chunk) { // Update the received bytes received_bytes += chunk.length; if(showProcess) showProgress(progressWindow,received_bytes, total_bytes); }); req.on('end', function() { if(showProcess) progressWindow.close(); if(targetPath.includes('.zip')){ var zip = new archiver(targetPath); zip.extractAllTo(targetPath.substr(0,targetPath.length-4-packetName.length)); fs.unlinkSync(targetPath); } if(callback) callback(packetName); console.log("RETURN"); return; }); } 

El uso del sistema de callback crea muchos caos y también es redundante, esperaba otra solución. ¡Gracias por tu tiempo!

Donde actualmente console.log("RETURN") puede resolver una Promesa que devuelve downloadFile . Luego, simplemente puede esperar las llamadas en sus sucursales if (y, por supuesto, pasar la callback async a ipcMain ).

La estructura en una forma más simple se vería como la siguiente

 function doJob () { return new Promise((resolve, reject) => { setTimeout(() => { console.log('RETURN') resolve() }, 2000) }) } // ipcMain.on('play', async (event, payload) => { ... }) (async () => { if (true) { await doJob() } if (true) { await doJob() } })() 

Puedo ver que está afectando a launcherDir en las tres veces que lo usa en! If siempre ejecutará el primer proceso, incluso si falla, es decir, el último si revisará launcherDir + “\ natives” + “\ bin” o es este el deseado comportamiento si no creo que todos tus if’s fallarán