gpt4 book ai didi

javascript - 如何通过消除双重等待和 DRY 代码进行重构?

转载 作者:行者123 更新时间:2023-12-03 22:59:41 26 4
gpt4 key购买 nike

我怀疑哪个是管理此 Web 应用程序中的许多服务客户端的最佳策略。
就用户设备 RAM 和 Javascript 执行速度(主线程操作)之间的良好折衷而言,“最佳”。
这就是我现在正在做的,这是主文件:

  • main.ts:
  • import type { PlayerServiceClient } from './player.client';
    import type { TeamServiceClient } from './team.client';
    import type { RefereeServiceClient } from './referee.client';
    import type { FriendServiceClient } from './friend.client';
    import type { PrizeServiceClient } from './prize.client';
    import type { WinnerServiceClient } from './winner.client';
    import type { CalendarServiceClient } from './calendar.client';

    let playerService: PlayerServiceClient;
    export const player = async (): Promise<PlayerServiceClient> =>
    playerService ||
    ((playerService = new (await import('./player.client')).PlayerServiceClient()),
    playerService);

    let teamService: TeamServiceClient;
    export const getTeamService = (): TeamServiceClient =>
    teamService ||
    ((teamService = new (await import('./team.client')).TeamServiceClient()),
    teamService);

    let refereeService: RefereeServiceClient;
    export const getRefereeService = (): RefereeServiceClient =>
    refereeService ||
    ((refereeService = new (await import('./referee.client')).RefereeServiceClient()),
    refereeService);

    let friendService: FriendServiceClient;
    export const getFriendService = (): FriendServiceClient =>
    friendService ||
    ((friendService = new (await import('./friend.client')).FriendServiceClient()),
    friendService);

    let prizeService: PrizeServiceClient;
    export const getPrizeService = (): PrizeServiceClient =>
    prizeService ||
    ((prizeService = new (await import('./prize.client')).PrizeServiceClient()),
    prizeService);

    let winnerService: WinnerServiceClient;
    export const getWinnerService = (): WinnerServiceClient =>
    winnerService ||
    ((winnerService = new (await import('./winner.client')).WinnerServiceClient()),
    winnerService);

    let calendarService: CalendarServiceClient;
    export const getCalendarService = (): CalendarServiceClient =>
    calendarService ||
    ((calendarService = new (await import('./calendar.client')).CalendarServiceClient()),
    calendarService);

    // and so on... a lot more...
    如您所见,有 许多服务客户。
    我使用此代码是因为我认为基于几乎与客户端服务重叠的路由的 Web 应用程序结构更好:
    我的意思是,如果玩家来自 /home/players页面我可以像这样使用它:
  • 组件/players.svelte
  • import { getPlayerService } from "main";

    const playerService = await getPlayerService();
    const players = await playerService.queryPlayers();
    这样,如果 PlayerService不存在,此时导入并返回,否则返回之前导入并实例化的那个。
    由于用户经常这样切换页面,我可以避免这些客户端的突然创建和销毁,对吗?
    但是这样我使用 全局变量 我不喜欢使用,我正在使用 详细、干燥和长代码 在每个组件中。
    有没有办法在组件中使用以下代码?
    import { playerService } from "main";

    const players = await playerService.queryPlayers();
    你建议我怎么做?

    最佳答案

    您正在实现的模式是“延迟加载”和“单例”。
    您可以有一个服务工厂来实现这些模式并将其用于每个服务:
    文件 serviceFactory.js

    const serviceMap = {};

    export function getService(serviceName) {
    return serviceMap[serviceName] ?? (serviceMap[serviceName] = import(serviceName).then(x => new x.default));
    }
    ECMAScript 模块标准将负责执行 serviceFactory.js在应用程序中只编码一次(无论您导入多少次),因此您可以将单例保存在分配给 serviceFactory.js 的私有(private)顶级变量的映射中模块。
    该服务工厂意味着每个服务都使用 default 导出。像这样的关键字:
    export default class SomeService {
    constructor() {
    // ...
    }

    fetchSomething() {
    // ...
    }
    }
    然后,使用以下代码在应用程序中的任何位置使用服务:
    import { getService } from './serviceFactory.js';

    const service = await getService('./services/some.service.js');
    const something = await service.fetchSomething();
    如果你真的想删除双 await ,您可以像这样将其封装在服务工厂中:
    const serviceMap = {};

    export function getService(serviceName) {
    return serviceMap[serviceName] ?? (serviceMap[serviceName] = resolveService(serviceName));
    }

    function resolveService(name) {
    const futureInstance = import(name).then(x => new x.default);

    const handler = {
    get: function (target, prop) {
    return function (...args) {
    return target.then(instance => instance[prop](...args));
    }
    }
    }

    return new Proxy(futureInstance, handler);
    }
    它允许您编写以下代码:
    const something = await getService('./services/some.service.js').fetchSomething();
    这允许在您需要的确切代码行中加载服务。
    如果它不打扰您使用静态 import 加载它因为你需要 import { playerService } from "main";语法,您可以像这样在 中公开每个服务每个服务一个文件 :
    export const playerService = getService('./services/player.service.js');
    我在这里发布了完整的工作演示: https://github.com/Guerric-P/lazy-singletons-demo

    关于javascript - 如何通过消除双重等待和 DRY 代码进行重构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67006908/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com