主进程与渲染进程处理Promise,预加载层openFile需async/await吗?
关于Electron预加载层Promise与async/await的疑问
问题1
考虑到渲染进程(renderer)与主进程(main)均在处理Promise,若预加载层的openFile()未使用async/await,下方代码是否会强制进程变为同步?
contextBridge.exposeInMainWorld('myAPI', { openFile: () => ipcRenderer.invoke('dialog:openFile'), ... } )
问题2
若下方带async/await的代码完全多余,能否解释为何可像上述代码那样省略async/await?
contextBridge.exposeInMainWorld('myAPI', { openFile: async () => await ipcRenderer.invoke('dialog:openFile'), ... } )
补充代码示例
// renderer.js el.addEventListener('click', async ()=>{ const filePath = await window.myAPI.openFile() el.textContent = filePath })
// main.js ipcMain.handle('dialog:openFile', async ()=>{ const { canceled, filePaths } = await dialog.showOpenDialog() if (!canceled) return filePaths[0] })
回答
针对问题1:不会强制进程变为同步
ipcRenderer.invoke()方法本身就会返回一个Promise,预加载层的openFile直接返回这个Promise对象时,渲染进程里的await window.myAPI.openFile()本质是在等待该Promise完成,整个流程始终是异步的,完全不会触发同步执行逻辑。
针对问题2:带async/await的版本确实多余,原因如下
async函数的特性是自动将返回值包装为Promise,而ipcRenderer.invoke()已经返回了一个Promise。这里用await只是把已有的Promise拆解开,再重新包装成一个新的Promise,属于完全不必要的额外操作。- 直白点说:
() => ipcRenderer.invoke(...)和async () => await ipcRenderer.invoke(...)的执行效果完全一致,后者只是多了一层无意义的Promise包装。
结合补充代码来看,主进程的ipcMain.handle回调、渲染进程的点击回调都是异步函数,整个调用链依赖Promise传递数据,预加载层省略async/await不会影响异步流程的正常运行。
内容的提问来源于stack exchange,提问作者oldboy
相关产品推荐
相关产品推荐

