Electron global variable garbage collected if rend

2019-03-01 13:47发布

问题:

In Electron, I have my main process opening a BrowserWindow. The BrowserWindow loads one html page and then the same window eventually loads another html page.

main.js

var mainWindow;
global.mainState = {
  settings: {}
}
mainWindow = createWindow('main', {
  width: 1000,
  height: 800,
});
if (curState == 'load') {
  mainWindow.loadURL(`file://${__dirname}/interface/load.html`, {})
}
if (curState == 'login') {
  mainWindow.loadURL(`file://${__dirname}/interface/login.html`, {})
}

load.html

const remote = require('electron').remote;
var testGlobal = remote.getGlobal('mainState')
testGlobal.settings = 'test value'
testGlobal.settings.inner = 'test value2'

When main.js loads the second page (login.html), will the global variable be deleted/dereferenced? The docs say that if the renderer process dereferences a global variable then the variable will be gc'd. When I try to test this I get inconsistent results and I would just like some explanation from someone more wise than I.

回答1:

testGlobal will be garbage collected, since the site changes. global.mainState will not be deleted, however it will also not change when you call testGlobal.settings = 'test value', because remote.getGlobal() just gives you a copy of mainState and not a reference.

I would suggest you use ipcMain and ipcRenderer to sync the global variable yourself.



回答2:

Use IPC to Set the Global's Value.

@RoyalBingBong is correct in that "remote.getGlobal() just gives you a copy of mainState and not a reference."

It might seems like you're changing the value of the global variable, but you're not. So, for example, when I refresh my Electron browser window, the value of that global variable would revert to what it was.

I found that the only way to properly change the value of the global variable was to use ipcMain and ipcRenderer (the verbose way).

main.js

const { ipcMain } = require( "electron" );

ipcMain.on( "setMyGlobalVariable", ( event, myGlobalVariable ) => {
  global.myGlobalVariable = myGlobalVariable;
} );

renderer.js

const { ipcRenderer, remote } = require( "electron" );

// Set MyGlobalVariable.
ipcRenderer.send( "setMyGlobalVariable", "Hi There!" );

// Read MyGlobalVariable.
remote.getGlobal( "MyGlobalVariable" ); // => "Hi There!"

Now, I can refresh my Electron window or spin up a new renderer process and value of the global variable will correctly be what I set it to, in this example, "Hi There!".

You can also see that for reading it, I use the simpler remote.getGlobal. I haven't tested whether this will cause problems when the value changes and the value of this doesn't get updated. I might have to come back to this answer if that's the case and use another ipcMain and ipcRenderer to manually read the global variable.