Как импортировать одноэлементный класс, подобный сервису, с помощью System.js?

У меня есть Singleton-Class FooService, который загружается через карту импорта. Я хотел бы (а) дождаться этого и использовать его в различных асинхронных функциях, например:

declare global {
  interface Window {
    System: System.Module
  }
}

const module = window.System.import('@internal/foo-service')
const fooService = module.FooService

async function func1() {
  await fooService.doBar()
  .
  .
}

async function func2() {
  await fooService.doBar2()
  .
  .
}

Но я мог заставить его работать только так:

declare global {
  interface Window {
    System: System.Module
  }
}

async function getfooService() {
  const module = await window.System.import('@internal/foo-service')
  return module.FooService
}

function func1() {
  getfooService().then(fooService => fooService .doBar())
  .
  .
}

function func2() {
  getfooService().then(fooService => fooService.doBar2())
  .
  .
}

Как я могу добиться этого, не загружая его заново каждый раз, когда я хочу его использовать?

Модули не загружаются заново, независимо от того, как часто вы их импортируете.

Bergi 01.01.2021 20:28

Почему бы вам просто не написать import { FooService } from '@internal/foo-service';?

Bergi 01.01.2021 20:30

Модуль уже образует синглтон. Не нужно использовать «одиночку class».

Bergi 01.01.2021 20:30

@Bergi Он загружается через System.js, потому что он загружается асинхронно. Обычно его импорт приводит к ошибке.

leonheess 04.01.2021 00:08
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
4
312
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

вы можете попробовать обернуть его в IIFE, например:


declare global {
  interface Window {
    System: System.Module
  }
}

// Wrap rest of the code in IIFE
(async () => {
  const module = await window.System.import("@internal/foo-service");

  // Use await keyword if FooService/doBar/doBar2 are async
  const fooService = await module.FooService;
  const doBar = await fooService;
  const doBar2 = await fooService;

  async function func1() {
    doBar();
  }

  async function func2() {
    doBar2();
  }
})();

Поскольку это модуль Vuex, я не думаю, что это возможно:/

leonheess 04.01.2021 00:06
Ответ принят как подходящий

Ваше первое предположение было почти правильным. Обратите внимание, что module, возвращаемый import, является обещанием, поэтому вам нужно использовать его как

const fooService = window.System.import('@internal/foo-service').then(module =>
  module.FooService
);

async function func1() {
  (await fooService).doBar();
//^                ^
  …
}

async function func2() {
  (await fooService).doBar2();
//^                ^
  …
}

Кстати, я бы порекомендовал избегать использования «объекта модуля» FooService (или, что еще хуже, класса), а вместо этого просто export именованные функции, чтобы вы могли удалить .then(module => module.FooService).

Работает отлично, но теперь Jest спотыкается с Cannot read property 'import' of undefined, чего раньше не было

leonheess 05.01.2021 15:08

@leonheess Я не думаю, что в Jest есть window.System. Вы, вероятно, должны задать новый вопрос об этом, хотя

Bergi 05.01.2021 16:23

Я создал один здесь

leonheess 07.01.2021 10:28

Другие вопросы по теме