如何导出已解决的承诺并再次导入

Posted

技术标签:

【中文标题】如何导出已解决的承诺并再次导入【英文标题】:How to export a resolved promise and import it again 【发布时间】:2020-09-27 05:24:53 【问题描述】:

我想导出 ApolloServer 函数,以便稍后在测试套件中导入,或者只是在 index.ts 文件中导入。

工作代码:

  // src/index.ts
;(async () => 
  const app = express()

  await createConnections()

  const apolloServer = new ApolloServer(
    schema: await buildSchema(
      resolvers: [HelloWorldResolver, MovieResolver],
    ),
    context: ( req, res ) => ( req, res ),
  )

  apolloServer.applyMiddleware( app, cors: false )

  app
    .listen( port: ENVIRONMENT.port, host: ENVIRONMENT.host , () => 
      console.log(
        `Server ready at http://$ENVIRONMENT.host:$ENVIRONMENT.port/graphql`
      )
    )
    .on('error', function (error) 
      console.log(`Failed starting server: $error`)
    )
)()

我试图将它提取到一个单独的文件中:

// src/apolloServer.ts
export const apolloServer = (async () => 
  return new ApolloServer(
    schema: await buildSchema(
      resolvers: [HelloWorldResolver, MovieResolver],
    ),
    context: ( req, res ) => ( req, res ),
  )
)()

然后消费它:

// src/index.ts
import  apolloServer  from './apolloServer'
apolloServer.applyMiddleware( app, cors: false )

抛出的错误是:

(node:13848) UnhandledPromiseRejectionWarning: TypeError: apolloServer_1.apolloServer.applyMiddleware is not a function

如何导出和导入这个函数?

【问题讨论】:

【参考方案1】:

在您提取的版本中,您没有将apolloServer 定义为ApolloServer 的实例,而是作为运行async 函数的结果。由于async 函数总是返回一个 Promise 对象,apolloServer 现在是一个 Promise 对象。

您应该使用thenawait 获得它所解析的值。

在您的第一个代码版本中,您肯定在async 函数的上下文中运行,而在第二个版本中,import 部分发生在async 函数之外。你也应该在那里重复async 模式:

import  apolloServer  from './apolloServer'
(async () => 
    (await apolloServer).applyMiddleware( app, cors: false )
)();

【讨论】:

我已经更新了 OP。问题是buildSchema 返回了一个 Promise。所以无论如何我们都需要等待。如何从索引文件中提取ApolloServer 代码? 查看我的答案。 感谢您的更新。我想应该是await apolloServer() 只有在更改导入的脚本时才需要执行,就像在另一个答案中一样。但是在您的问题中,您在导入的脚本中执行了它,并在 async 表达式之后附加了 () 。因此,按照你的问题,你会得到一个承诺,这里不应该有()。承诺不是函数。【参考方案2】:

构建一个函数来生成全新的 ApolloServer 实例。 在其他任何地方运行该函数以生成一个全新的 ApolloServer

// src/apolloServer.ts
export const getApolloServer = async () => 
  return new ApolloServer(
    schema: await buildSchema(
      resolvers: [HelloWorldResolver, MovieResolver],
    ),
    context: ( req, res ) => ( req, res ),
  )

// src/index.ts
import  getApolloServer  from './apolloServer'
const clonedServer = await getApolloServer();
clonedServer.applyMiddleware( app, cors: false )

【讨论】:

以上是关于如何导出已解决的承诺并再次导入的主要内容,如果未能解决你的问题,请参考以下文章

如何等到承诺完成后再继续循环

如何使用 Redux Promise 为我的组件获得已解决的承诺?

为啥一个已解决的承诺仍处于待处理状态?

如何同步确定JavaScript Promise的状态?

在 Ember 车把模板中呈现已解决的承诺值

承诺已解决但返回部分数据 - 其余“未定义”