【发布时间】:2021-02-18 19:30:10
【问题描述】:
我正在使用 Electron 打包一个 R Shiny 应用程序。它在我的电脑和我测试过的大多数电脑上都能正常工作。但是,在某些情况下它会崩溃(通常在速度较慢的计算机中)。我不熟悉 Javascript,我正在尝试了解我正在使用的 JS 代码中发生了什么。
在试图找出导致崩溃的原因一段时间后,我注意到应该仅在我的应用尚未显示时执行的 while 循环实际上又执行了一次。我怀疑这可能会导致问题(尽管我不确定)。以下是我在电子应用程序准备就绪时运行的内容。
app.on('ready', async () => {
let shinyRunning = false
let i = 1
loadingSplashScreen = createSplashScreen('loading')
mainWindow = createWindow()
try {
rShinyProcess = execa(NODER,
['-e', 'rbingo::launch_app(options = list(port = ' + srv.address().port + '))'], {
env: {
// Necessary for letting R know where it is and ensure we're not using another R
'WITHIN_ELECTRON': 'T', // can be used within an app to implement specific behaviour
'RHOME': rResources,
'R_HOME_DIR': rResources,
'R_LIBS': path.join(rResources, "library"),
'R_LIBS_USER': path.join(rResources, "library"),
'R_LIBS_SITE': path.join(rResources, "library"),
'R_LIB_PATHS': path.join(rResources, "library")
}
})
} catch {
console.log(new Date().toISOString() + ':rshinyprocess execa catched')
console.log(e)
}
mainWindow.loadURL('http://127.0.0.1:' + srv.address().port);
try {
while(!shinyRunning) {
const wait_res = await waitFor(1000);
console.log(new Date().toISOString() + ': Trying to connect...' + i)
i += 1
console.log('shinyRunning status: ' + shinyRunning)
mainWindow.webContents.executeJavaScript('window.Shiny.shinyapp.isConnected()', true)
.then((result) => {
shinyRunning = true
mainWindow.show()
loadingSplashScreen.hide()
loadingSplashScreen.close()
console.log(new Date().toISOString() + ': Successfully connected to the app')
})
.catch((result) => {
})
}
} catch (e) {
console.log(new Date().toISOString() + ': Error catched while trying to load the app.')
}
// Emitted when the window is closed.
mainWindow.on('closed', function () {
console.log(new Date().toISOString() + ': mainWindow.closed()')
cleanUpApplication()
})
mainWindow.webContents.on('did-fail-load', (event, code, desc, url, isMainFrame) => {
console.log(new Date().toISOString() + ': DID FAIL LOAD - ', code, desc, url, isMainFrame);
});
})
23:56:38.475 > Application Started
2020-11-06T02:56:38.489Z: Listening on port 49271
2020-11-06T02:56:39.593Z: Trying to connect...1
shinyRunning status: false
2020-11-06T02:56:40.594Z: Trying to connect...2
shinyRunning status: false
2020-11-06T02:56:41.594Z: Trying to connect...3
shinyRunning status: false
2020-11-06T02:56:42.594Z: Trying to connect...4
shinyRunning status: false
2020-11-06T02:56:42.949Z: Successfully connected to the app
2020-11-06T02:56:43.594Z: Trying to connect...5 <------ THIS SHOULDN'T BE HERE
shinyRunning status: true <------ THIS SHOULDN'T BE HERE
我的问题是:当shinyRunning 是true 时,是什么导致这个while 循环额外执行一次?
如果您需要有关我的应用或整个 .js 文件的更多信息,我也可以分享。
谢谢, 托马斯
PS: waitFor 只是
function waitFor(miliseconds) {
return new Promise(resolve => {
setTimeout(() => {
resolve('resolved');
}, miliseconds);
});
}
编辑:
感谢@cuspymd 的回答和@syarul 的评论。
我已经更新了代码,现在我不再使用 while 循环了,控制台看起来更好了。
...
mainWindow.loadURL('http://127.0.0.1:' + srv.address().port);
try {
await mainWindow.webContents.executeJavaScript('window.Shiny.shinyapp.isConnected()', true)
.then((result) => {
mainWindow.show()
loadingSplashScreen.hide()
loadingSplashScreen.close()
console.log(new Date().toISOString() + ': Successfully connected to the app')
shinyRunning = true
})
.catch((result) => {
})
} catch (e) {
console.log(new Date().toISOString() + ': Error catched while trying to load the app.')
}
...
11:02:51.653 > Application Started
2020-11-06T14:02:51.668Z: Listening on port 63065
2020-11-06T14:02:56.079Z: Successfully connected to the app
【问题讨论】:
-
这很奇怪,为什么要把异步函数放在while循环中?我在stackoverflow [javascript]中到处都看到过很多这样的问题。将异步代码放在同步循环代码中是非常糟糕的代码实践
-
我是 JS 的初学者。这是我复制并粘贴的代码。我已经用@cuspymd 的建议更新了我的代码,现在我认为它工作得更好。我还删除了 while 循环。这和你的做法相似吗?
标签: javascript r shiny electron