日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

async function_Electron IPC 通信如何使用 async/await 调用?

發(fā)布時間:2025/3/19 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 async function_Electron IPC 通信如何使用 async/await 调用? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言碎語

此想法是在使用 electron 進(jìn)程間通信(IPC)過程中,無法忍受其 API 的使用不友好性而產(chǎn)生。

為了提高代碼可讀性、可維護(hù)性,而不得已造輪子了。

生命在于折騰,其樂無窮。

Electron 中 IPC 的通信方式

在 Electron 中分為兩個進(jìn)程:

  • Main Process(主進(jìn)程)。是 Node.js 跑的一個進(jìn)程,可以調(diào)用 Node API 和 Electron 封裝好的 API。
  • Renderer Process(渲染進(jìn)程)。是運(yùn)行在 Chromium 中的 web 進(jìn)程。
  • 因?yàn)?Electron 出于安全考慮,渲染進(jìn)程的 API 是有限制的。因?yàn)?web 端可能會加載第三方 js 代碼,不可能讓第三方為所欲為的。

    假如在一些場景中我可能要獲取某個文件夾下的文件列表(舉例而已),在 Node 中使用 fs 模塊即可完成,但是在 web 端無法使用 fs API。

    這時候就需要使用 IPC 進(jìn)程通信來解決。

    就像是 nodejs 中的子進(jìn)程一樣
    通過 spawn 方法開啟一個子進(jìn)程,兩個進(jìn)程之間只能通過 IPC 協(xié)議通信

    主進(jìn)程:

    import { IpcMain } from 'electron' import fs from 'fs'// 監(jiān)聽渲染進(jìn)程發(fā)來的 getDir 請求 IpcMain.on('getDir', (event, data) => {fs.readdir('path', (err, files) => {if (err) {// 響應(yīng)渲染進(jìn)程獲取失敗了event.reply('dir-result', 'err')} else {const result = files.map(/* do something */)// 響應(yīng)渲染進(jìn)程獲取到的結(jié)果event.reply('dir-result', result)}}) })

    渲染進(jìn)程:

    const { ipcRenderer } = require('electron')// 先監(jiān)聽主進(jìn)程發(fā)來的消息 ipcRenderer.on('dir-result', (event, data) => {// do something })// 發(fā)送給主進(jìn)程 ipcRenderer.send('getDir', '/Users')

    代碼很簡單,主進(jìn)程先監(jiān)聽渲染進(jìn)程消息,渲染進(jìn)程再監(jiān)聽主進(jìn)程消息,然后渲染進(jìn)程發(fā)起消息。

    很好理解,只不過渲染進(jìn)程的操作過于繁瑣。

    假如此邏輯放入vue 組件中,那么需要在 created 中進(jìn)行監(jiān)聽主進(jìn)程消息,在 destroyed 中進(jìn)行解綁改事件。

    那么怎么去優(yōu)化此處的體驗(yàn)?zāi)?#xff1f;造輪子唄~

    對 IPC 通信方式進(jìn)行二次封裝

    先看下面這段代碼:

    此處為渲染進(jìn)程部分代碼,以 React 組件舉例。// 渲染進(jìn)程 import React, { useState, useEffect } from 'react' import request from './request'export default function IpcTest () {const [list, setList] = useState([])useEffect(() => {init()}, [])// 進(jìn)行初始化操作const init = async () => {// request 取代 ipcRenderer.send 和 ipcRenderer.onconst result = await request('test', { a: 1 })// result => ['1', '2', '3'] from Main ProcesssetList(result)} }// 主進(jìn)程 import server from './server' // 類似 koa-router 的使用方式 server.use('test', async (ctx, data) => {// data => { a: 1 } from Renderer Processconst result = await doSomething(data)ctx.reply(['1', '2', '3']) })

    上面代碼以 http 請求的寫法來處理了 IPC 通信。其中 request 與 server 則是進(jìn)行二次封裝后的輪子。

    這樣使用 async/await 的方式來處理,是不是就輕松多了?代碼的可讀性、可維護(hù)性也增強(qiáng)了。

    而且在封裝的過程中完全可以按照 axios 的 API 來處理,便于代碼遷移(當(dāng)然這里業(yè)務(wù)邏輯的通用性另說)。

    廢話不多說下面來看一下處理原理。

    Electron IPC 異步封裝

    request 大致實(shí)現(xiàn)邏輯:

    const { ipcRenderer } = require('electron')const _map = new Map()ipcRenderer.on('from-server', (event, params) => {const cb = _map.get(params.symbol)if (typeof cb === 'function') {_map.delete(params.symbol)cb()} })export default request (type, data) {const _symbol = Date.now() + typereturn new Promise(resolve => {_map.set(_symbol, data => {resolve(data)})ipcRenderer.send('from-type', {_symbol, type, data})}) }

    server 大致實(shí)現(xiàn)邏輯:

    import { ipcMain } from 'electron'const _map = new Map()ipcMain.on('from-client', (event, params) => {const reply = function (data) {event.reply('from-server', {_symbol: params._symbol,// data 傳遞給客戶端,最終 resolve 它data})}const ctx = {reply,type: params.type}const cb = _map.get(params.type)if (typeof cb === 'function') {cb(ctx, params.data)} else {// 沒有注冊~} })export default function use (type, callback) {_map.set(type, cb) }

    一個簡單基礎(chǔ)版的 IPC 封裝就完成了,在此功能上還可以增加一些 timeout、多次調(diào)用只獲取最后一次返回的數(shù)據(jù)類似的功能,這些在原生的 electron IPC API 上是無法實(shí)現(xiàn)的(也可能是我文檔看的少沒有發(fā)現(xiàn))。

    測試

    起初在做單元測試時,走了彎路。

    因?yàn)?IPC 是兩個進(jìn)程之間交互的一個過程,當(dāng)時一直在想如何簡單的啟動一個 electron 容器進(jìn)行測試。

    后來又根據(jù)官網(wǎng)介紹想通過 Node 啟動兩個進(jìn)程來模擬 IPC 交互過程,這其實(shí)也是個彎路。

    其實(shí)需要做的只要保證 use、request 方法能跑通、保證內(nèi)部邏輯運(yùn)行正確即可。

    最后直接模擬了 ipcRenderer (on 和 send)、ipcMain (on 和 reply),將這 4 個方法的輸入與輸出與 electron 提供的 API 表現(xiàn)一致即可達(dá)到目的。

    類似于 測試驅(qū)動 模擬一個測試環(huán)境可以讓代碼正常運(yùn)行,且表現(xiàn)一致。

    總結(jié)

    以上是生活随笔為你收集整理的async function_Electron IPC 通信如何使用 async/await 调用?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。