使用 ES6的 Proxy 设计模式-代理模式 实现更优雅的 Electron IPC 服务,学习来源:GitHub - maxiee/RayBook: 一个功能强大的跨平台电子书管理器和阅读器,支持多种格式,集成微信读书,基于 Electron 和 React 构建。

export interface IUserService {
 getUserInfo(userId: string):Promise<ApiResponse<UserInfo | null>>;
 getUserFile(fileId: string): Promise<ApiResponse<IUserFile[]>>;
}
 
class UserService implements IUserService {
  async getUserInfo(userId:string): Promise<ApiResponse<UserInfo | null>> {
    return ..
  }
 
  async getUserFile(fileId: string): Promise<ApiResponse<IUserFile[]>> {
    return ..
  }
}
 
export const userService = new UserService();

IPC

createIpcProxy

通过 Proxy 创建一个代理服务

const { ipcRenderer } = window.require('electron');
 
export function createIpcProxy<T extends object>(serviceName: string): T {
  return new Proxy({} as T, {
    get: (target, prop) => {
      return (...args: any[]) => ipcRenderer.invoke(`${serviceName}:${prop.toString()}`, ...args);
    }
  });
}

用于实现调用: userServiceRender.getUserInfo(id) 时自动转换为执行

ipcRenderer.invoke(`UserService:getUserInfo`, { id });

registerIpcHandlers 注册IPC

import { ipcMain } from "electron";
 
export function registerIpcHandlers(service: any) {
  for (const method of Object.getOwnPropertyNames(
    Object.getPrototypeOf(service)
  )) {
    if (typeof service[method] === "function") {
      ipcMain.handle(
        `${service.constructor.name}:${method}`,
        async (event, ...args) => {
          try {
            return await service[method](...args);
          } catch (error) {
            console.error(
              `Error in ${service.constructor.name}:${method}:`,
              error
            );
            throw error;
          }
        }
      );
    }
  }
}

创建IPC服务

export const userServiceRender = createIpcProxy<IUserService>("UserService");

注册 IPC 处理程序

registerIpcHandlers(bookService);
registerIpcHandlers(bookFileServ)

调用

const userinfo = await userServiceRender.getUserInfo(id);

Tauri 中优化 IPC 使用方式 Tauri IPC 调用封装