【问题标题】:What is the proper way to restart an Electron app?重新启动 Electron 应用程序的正确方法是什么?
【发布时间】:2021-09-16 22:09:27
【问题描述】:

在此 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');
});

生成以下应用程序菜单:

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

【问题讨论】:

    标签: javascript electron


    【解决方案1】:

    重启电子应用的正确方法是:

    app.relaunch()
    app.exit()
    

    official documentation

    【讨论】:

    • 这根本不能回答问题。实际上,它只是确认了 OP 所说的:“在调用 app.relaunch 之后应该执行 app.quitapp.exit
    【解决方案2】:
    1. quit 优雅地关闭所有窗口然后退出,而 exit 则简单地终止应用程序而不考虑其他任何事情,例如 Node.js 中的 process.exit。在大多数情况下,为了安全起见,您需要使用 quit

    2. 最好先调用relaunch 以防止出现竞争情况。由于事件循环的工作方式,这在生产中几乎不会发生,但这只是一种很好的做法。

    【讨论】:

    • 你在想什么样的竞态条件?你有没有一个例子说明在开发过程中可能发生的事情app.relaunch(); app.quit()(按此顺序)会减轻并且不会在生产中发生?
    • 嘿@customcommander,我在my answer 上解释了这个竞争条件。如果您仍有任何问题,请在此处发表评论,我会尽量让您更清楚:)
    【解决方案3】:

    app.relaunch

    根据app.relaunchdocs

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

    (...)

    注意,此方法执行时不会退出应用,需要在调用app.relaunch后调用app.quitapp.exit才能使应用重启。

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

    我们可以假设:

    1. 只调用app.relaunch() 不会做任何事情(直到用户关闭应用程序,然后它才会重新启动);
    2. 您可以调用app.quit()app.exit() 来关闭应用程序,然后它将重新启动,因为您已经调用了app.relaunch()

    app.quit

    再次引用docs

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

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

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

    app.exit

    docs 声明:

    所有窗口都会在不询问用户的情况下立即关闭,并且不会发出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,请关闭我的应用程序。哦,关闭后重新启动它。”。它在大多数情况下都会起作用,但这只是因为app.exit 的执行速度比app.relaunch 慢。它们没有同步运行。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-10
      • 2016-08-12
      • 2019-09-08
      • 1970-01-01
      • 2012-12-19
      • 1970-01-01
      • 2019-05-26
      相关资源
      最近更新 更多