Electron中mainWindow.loadURL()异步化,解决Express服务启动加载失败问题
解决Electron主窗口早于Express服务器启动导致页面加载失败的问题
方案一:等待服务器(含Mongoose)完全启动后再创建窗口
这种方案从根源避免加载失败,确保Express服务器和Mongoose数据库连接都准备就绪后,再打开Electron窗口。
步骤1:修改Express服务器文件(./app.js)
将服务器启动逻辑封装为Promise,确保Mongoose连接成功后再启动Express服务:
const express = require('express'); const mongoose = require('mongoose'); const app = express(); // 你的Express路由、中间件配置... // 封装启动逻辑为Promise async function startServer() { // 等待Mongoose连接完成 await mongoose.connect('你的数据库连接字符串'); console.log('Mongoose连接成功'); // 启动Express并返回Promise return new Promise((resolve) => { const server = app.listen(3000, () => { console.log('Express服务器运行在http://localhost:3000'); resolve(server); }); }); } // 导出启动Promise module.exports = startServer();
步骤2:修改Electron主进程文件(index.js)
等待服务器启动完成后再创建窗口:
const {app, BrowserWindow} = require('electron'); // 导入服务器启动Promise const serverPromise = require('./app'); let mainWindow function createWindow () { mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } }) mainWindow.loadURL('http://localhost:3000') mainWindow.on('closed', function () { mainWindow = null }) } // 等待服务器就绪后创建窗口 app.whenReady().then(async () => { await serverPromise; createWindow(); }); app.on('resize', function(e,x,y) { mainWindow.setSize(x, y); }); app.on('window-all-closed', function () { if (process.platform !== 'darwin') { app.quit() } }) app.on('activate', function () { if (mainWindow === null) { createWindow() } })
方案二:让Electron窗口自动重试加载直到成功
如果不想修改Express代码,可通过监听窗口加载失败事件,自动重试加载页面。
修改Electron主进程文件(index.js):
const {app, BrowserWindow} = require('electron'); const server = require('./app'); let mainWindow const RETRY_INTERVAL = 1000; // 重试间隔(毫秒) function createWindow () { mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } }) // 定义页面加载函数 function loadPage() { mainWindow.loadURL('http://localhost:3000') } loadPage(); // 加载失败时自动重试 mainWindow.webContents.on('did-fail-load', () => { setTimeout(loadPage, RETRY_INTERVAL); }) mainWindow.on('closed', function () { mainWindow = null }) } app.on('ready', createWindow) app.on('resize', function(e,x,y) { mainWindow.setSize(x, y); }); app.on('window-all-closed', function () { if (process.platform !== 'darwin') { app.quit() } }) app.on('activate', function () { if (mainWindow === null) { createWindow() } })
方案对比
- 方案一:无冗余重试,启动逻辑更严谨,适合对服务就绪状态有严格要求的场景。
- 方案二:实现简单,无需改动Express代码,适合快速调试或轻量场景。
内容的提问来源于stack exchange,提问作者José Ricardo Cedeño García
相关产品推荐
相关产品推荐

