首页 > 解决方案 > Electron 的异步问题

问题描述

我目前正在开发一个 Electron.js 应用程序,但我遇到了一个异步问题。我在三个要按顺序执行的 if 语句中具有三个函数 (downloadFile()),但它们是异步运行的;我已经尝试过使用 async/await 但它没有用。这是我的代码:

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;
});
}

使用回调系统会产生很多问题,而且也是多余的,我希望有另一种解决方案。感谢您的时间!

标签: javascriptnode.jsasynchronousasync-awaitelectron

解决方案


您目前可以在哪里console.log("RETURN")解决由downloadFile. 然后你可以简单地等待你的if分支中的调用(当然还有传递async回调ipcMain)。

更简单形式的结构如下所示

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()
  }
})()

推荐阅读