重启Electron应用程序的正确方法是什么?

22
在这个 Electron 文档 page 中,他们建议为了重启一个应用程序,应该在调用 app.relaunch 之后执行 app.quitapp.exit

请注意,当执行此方法时,它不会退出应用程序,您必须在调用 app.relaunch 后调用 app.quit 或 app.exit 才能使应用程序重启。

然而,经过实验,我发现顺序似乎并不重要。(请参见下面的示例。)我知道 app.quitapp.exit 并不完全相同。前者可以被中断并触发一些事件,而后者将强制应用程序退出而不触发任何事件或允许应用程序取消操作。

问题:假设始终可以强制应用程序退出,并且我们没有任何任务需要在应用程序退出之前执行,有:

  1. 有理由更喜欢 app.quitapp.exit 吗?
  2. 有理由说明为什么必须在调用 app.relaunch 后运行 app.quitapp.exit 吗?

这是一个非常简单的Electron应用程序:

package.json

{
  "name": "burrito",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "devDependencies": {
    "electron": "^4"
  }
}

main.js

const {app, BrowserWindow, Menu} = require('electron');
let mainWindow;

app.on('ready', () => {
  Menu.setApplicationMenu(
    Menu.buildFromTemplate([
      {role: 'appMenu', submenu: [

        {label: 'relaunch(); exit()', click() {
          app.relaunch();
          app.exit();
        }},

        {label: 'relaunch(); quit()', click() {
          app.relaunch();
          app.quit();
        }},

        {type: 'separator'},

        {label: 'exit(); relaunch()', click() {
          app.exit();
          app.relaunch();
        }},

        {label: 'quit(); relaunch()', click() {
          app.quit();
          app.relaunch();
        }}
      ]}
    ])
  );
  mainWindow = new BrowserWindow({width: 640, height: 480});
  mainWindow.loadFile('index.html');
});

生成以下应用程序菜单:

enter image description here

点击任何菜单项都会产生相同的结果:应用程序退出然后重新启动。

3个回答

26

重启Electron应用程序的正确方法是:

app.relaunch()
app.exit()

请参阅官方文档


2
这完全没有回答问题。实际上,它只是确认了OP所说的:“在调用app.relaunch后应该执行app.quitapp.exit”。 - Rafael Tavares

13

app.relaunch

根据 app.relaunch文档

当当前实例退出时,重新启动应用程序。

(...)

请注意,此方法执行时不会退出应用程序,您必须在调用 app.relaunch 后调用 app.quitapp.exit 来使应用程序重新启动。

多次调用 app.relaunch 会在当前实例退出后启动多个实例。

我们可以假设:

  1. 仅仅调用 app.relaunch() 不会有任何操作(除非用户关闭了应用程序,然后它会重新启动);
  2. 您可以通过调用 app.quit()app.exit() 关闭应用程序,然后它将重新启动,因为您已经调用了 app.relaunch()

app.quit

再次引用文档

尝试关闭所有窗口。首先将发出 before-quit 事件。如果所有窗口都成功关闭,将发出 will-quit 事件,并且默认情况下应用程序将终止。

此方法保证正确执行所有 beforeunloadunload 事件处理程序。某个窗口可能会通过在 beforeunload 事件处理程序中返回 false 来取消退出。

这意味着使用app.quit() 可能会或可能不会终止应用程序

app.exit

文档中指出:

所有窗口将立即关闭,而不会询问用户,before-quitwill-quit 事件也不会被发出。

因此,“立即”是一个危险的词。它意味着应用程序将在“尽可能快”的时间内关闭,并且它一定会关闭,但不是立即关闭。

我应该使用 app.quit 还是 app.exit 呢?

两者都有效,取决于您的用例:

  • 如果您的用户可能在某个屏幕上进行某些验证,以防止他们由于某些原因关闭应用程序,则 app.quit 可能更适合您。只需注意不要调用多次 app.relaunch(这会导致在退出当前实例后启动多个实例):
app.relaunch();
app.quit(); // maybe the application will be closed; maybe not
  • 如果您需要(或想要)立即关闭应用程序以应用某些设置,例如,无论当前发生什么情况,您应该调用app.exit。 这样做可以确保应用程序被关闭和重新启动:
app.relaunch();
app.exit(); // the application will be closed as soon as possible

为什么我应该首先调用 app.relaunch

因为它是合乎逻辑的。请参见下面的代码:

app.exit();
app.relaunch();

你在告诉 Electron:"嘿,Electron,请关闭我的应用程序。哦,在关闭后重新启动它。" 大多数情况下,这将有效,但这只是因为 app.exitapp.relaunch 执行得慢。它们不是同步运行的。

如果由于某种原因,Electron 在知道应该重新启动应用程序之前终止了它,那么对你来说这将是意外的行为,但这就是你告诉 Electron 要做的事情。


5
  1. quit 会优雅地关闭所有窗口并退出应用程序,与 exit 不同,后者只是简单地终止应用程序而不考虑其他任何事情,就像 Node 中的 process.exit。在大多数情况下,为了安全起见,您应该使用 quit

  2. 最好先调用 relaunch 以防止竞争条件。这在生产环境中几乎永远不会发生,因为事件循环的工作方式,但这只是良好的实践。


2
你在考虑哪种竞态条件?你有没有开发过程中可能发生的例子,app.relaunch(); app.quit()(按照这个顺序)可以减轻并且在生产环境中不会发生? - customcommander

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接