簡體   English   中英

在導出的類中使用異步 js 導入

[英]Using async js imports in exported classes

給定一個公開異步/動態導出的包。 我目前以這種方式導入(但我可以以不同的方式導入):

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

我打算將libEd一些函數作為類的一部分重新公開:

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

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

我怎樣才能做到這一點 ?


欲了解更多信息:

  • 暴露異步/動態導出的包是由 webpack 打包 webassembly 生成的。 我不確定我是否可以更改這部分的任何內容
  • 我絕對可以改變我導入那個包的方式
  • 我也可以改變我重新公開/分組功能的方式(並使用除類以外的其他東西)

我有幾種方法可以解決這個問題:

  1. 如果類不需要立即實例化,那么我將等待庫加載,然后將其傳遞給類構造函數。 這是最簡潔的方式,因為庫總是在類中定義。

  2. 如果在獲取庫之前必須實例化類,則類中的方法必須處理未定義(例如尚未加載)的情況。 然后您可以調用類似await myClassInstance.init()來獲取庫。 如果庫尚未加載,我通常會為每個方法提供一個回退,也許它返回一個空字符串或一個虛擬 UI。

編輯:為選項 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();
}

我最終選擇了三種方法之一:

  1. @Tim 的方法(接受的答案):在類屬性中包含導入,並在構造函數時await

    但是:可能存在與在每個實例中存儲導入相關的開銷。


  1. 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();
  }
}

但是:類 API 現在都是異步的,使用起來更尷尬。


  1. 在代碼開始時預加載導入。 並希望在調用類時完成加載。
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();
  }
}

但是:對於在導入完成之前/導入失敗之后創建類的實例的情況,這需要更好的錯誤處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM