首页 > 解决方案 > 从 ES6 模块中的 IIFE 返回解构对象

问题描述

我无法弄清楚如何在最后做到这一点

export {inMemoryDb, backup };

所以我想基本上将 IIFE 的返回值导出为命名导出。

InMemoryDB.ts

const result = (async () => {
  const inMemoryDb = newDb();
  await inMemoryDb.public.migrate();
  const backup = inMemoryDb.backup();

  return { inMemoryDb, backup };
})();

export result; 
// but I actually want to export it as { inMemoryDb, backup }

标签: javascriptecmascript-6

解决方案


所有导出都必须是静态的。这允许在模块分辨率中进行许多优化。因此,即使您有一个对象,也不能在没有明确指定的情况下将其属性导出为命名导出。


但是,您的代码的主要问题是异步。这就是阻止您按原样导出这些内容并导致导入它的复杂性的原因。

解决方案选项:

  1. 顶层提案(第 3 阶段await

    如果您使用支持它的平台,使用Babel之类的工具转译您的代码,或者使用TypeScript 3.8或更高版本,那么您已经可以使用此功能。

    它可以让你丢弃 IIAFE,所以你可以简单地写:

    export const inMemoryDb = newDb();
    await inMemoryDb.public.migrate();
    export const backup = inMemoryDb.backup();
    

    最好的一点是,您甚至不必在await使用时import进行操作,它会自动完成。

    这是此问题解决方案,但对于那些还没有访问此功能的人,这里有一些解决方法:

  2. Promise中导出所有内容

    好吧,这并不能回答您的问题,因为它不使用命名导出。顺便说一句,这几乎就是您的代码所做的!

     const result = (async () => {
       const inMemoryDb = newDb();
       await inMemoryDb.public.migrate();
       const backup = inMemoryDb.backup();
    
       return { inMemoryDb, backup };
     })();
    
     export default result; 
    

    为此,您的进口商需要:

     import result from './inMemoryDB.ts'
    
     (async () => {
       const { inMemoryDb, backup } = await result
       // Do stuff
     })()
    
  3. 在单独的 Promise 中导出所有内容

     const result = (async () => {
       const inMemoryDb = newDb();
       await inMemoryDb.public.migrate();
       const backup = inMemoryDb.backup();
    
       return { inMemoryDb, backup };
     })();
    
     export const inMemoryDb = result.then(({inMemoryDb}) => inMemoryDb); 
     export const backup = result.then(({backup}) => backup); 
    

    进口商代码:

     import { inMemoryDb, backup } from './inMemoryDB.ts'
    
     (async () => {
       const foo = await inMemoryDb
       const bar = await backup
       // Do stuff
     })()
    

推荐阅读