简体   繁体   English

在导出的类中使用异步 js 导入

[英]Using async js imports in exported classes

Given a package that exposes async/dynamic exports.给定一个公开异步/动态导出的包。 Which I currently import this way (but I could import it differently):我目前以这种方式导入(但我可以以不同的方式导入):

(async function() {
  const libEd = await import("../../.cache/ed25519wars/index.js");
})();

I intend to re-expose some functions from libEd as part of a class:我打算将libEd一些函数作为类的一部分重新公开:

export class Something {
  static from_X() {
    return libEd.genFromX();
  }

  do_Y() {
    return libEd.doY();
  }
}

How can I do this ?我怎样才能做到这一点 ?


For more info:欲了解更多信息:

  • The package that exposes async/dynamic exports is generated by webpack packing webassembly.暴露异步/动态导出的包是由 webpack 打包 webassembly 生成的。 I'm not sure if I can change anything about this part我不确定我是否可以更改这部分的任何内容
  • I could definitely change the way I import that package我绝对可以改变我导入那个包的方式
  • I could also change the way I re-expose / group the functions (and use something else than a class)我也可以改变我重新公开/分组功能的方式(并使用除类以外的其他东西)

There's a couple of ways I would approach this:我有几种方法可以解决这个问题:

  1. If the class doesn't need to be instantiated immediately, then I would await the library loading, then pass it to the class constructor.如果类不需要立即实例化,那么我将等待库加载,然后将其传递给类构造函数。 This is the cleanest way as the library is always defined within the class.这是最简洁的方式,因为库总是在类中定义。

  2. If the class must be instantiated before fetching the library, then methods in the class must handle the situation when it is not defined (eg not loaded yet).如果在获取库之前必须实例化类,则类中的方法必须处理未定义(例如尚未加载)的情况。 You can then call something like await myClassInstance.init() to fetch the library.然后您可以调用类似await myClassInstance.init()来获取库。 I typically provide a fallback for each method if the library is not loaded yet, perhaps it returns an empty string or a dummy UI.如果库尚未加载,我通常会为每个方法提供一个回退,也许它返回一个空字符串或一个虚拟 UI。

EDIT: adding TypeScript example for option 1编辑:为选项 1 添加 TypeScript 示例

interface MyLibrary {
  libraryMethod: () => void;
}

class ExampleClass {
  localLib: MyLibrary;

  constructor(lib: MyLibrary) {
    this.localLib = lib;
  }

  myClassMethod() {
    this.localLib.libraryMethod();
  }
}

async function run() {
  // first we fetch the remote library
  const myLibrary: MyLibrary | undefined = await import('/lib.js');

  // good practise to add some check here
  if (!myLibrary) {
    throw Error('failed to fetch myLib');
  }

  // then we create the class instance using the downloaded library
  const myClassInstance = new ExampleClass(myLibrary);

  // now we can call our class method which definitely has the remote library
  myClassInstance.myClassMethod();
}

I ended up settling on either of three methods:我最终选择了三种方法之一:

  1. @Tim's method (accepted answer): include the import in the class properties, and await at constructor time. @Tim 的方法(接受的答案):在类属性中包含导入,并在构造函数时await

    But: there might be overhead associated with storing the import in each instance.但是:可能存在与在每个实例中存储导入相关的开销。


  1. await ing in each method of the class to have the import defined there: await在类的每个方法中定义导入:
export class Something {
  static async from_X() {
    const libEd = await loadLibProm();
    return libEd.genFromX();
  }

  async do_Y() {
    const libEd = await loadLibProm();
    return libEd.doY();
  }
}

But: the class API is now all async and more awkward to use.但是:类 API 现在都是异步的,使用起来更尴尬。


  1. Pre-loading the import at code start.在代码开始时预加载导入。 And hoping the load is going to be finished when the class is called.并希望在调用类时完成加载。
let libEd: typeof import("../../.cache/ed25519wars/index.js");
async function loadLibProm(): Promise<
  typeof import("../../.cache/ed25519wars/index.js")
> {
  libEd = await import("../../.cache/ed25519wars/index.js");
  return libEd;
}
loadLibProm(); // this somehow starts running the promise ?? wut ? Anyways that's what we want

export class Something {
  static from_X() {
    return libEd.genFromX();
  }

  do_Y() {
    return libEd.doY();
  }
}

But: this needs better error handling for the case an instance of the class is created before the import is finished / after the import failed.但是:对于在导入完成之前/导入失败之后创建类的实例的情况,这需要更好的错误处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM