【问题标题】:Async/Await not working as expected with gRPC method使用 gRPC 方法时,Async/Await 无法按预期工作
【发布时间】:2021-08-02 08:25:43
【问题描述】:

这是初始化我正在使用的 gRPC 服务器的代码:

export const initServer = async (finalPort: number): Promise<string> => {
  let initStatus = 'initial';
  gRPCserver.addService(webcomponentHandler.service, webcomponentHandler.handler);

  // define the host/port for server
  await gRPCserver.bindAsync(
    `localhost:${finalPort}`,
    grpc.ServerCredentials.createInsecure(),
    (err: Error | null, port1: number) => {
      if (err != null) {
        console.error(err);
        log.info('Biding Error');
        initStatus = 'Binding Error';
      }
      // start the gRPC server
      gRPCserver.start();
      log.info(`startServer::gRPC server started, on port: ${port1}`);
      initStatus = 'OK';
    },
  );
  return initStatus;
};

我正在尝试将该 initStatus 返回到此函数:

type StartServerType = () => Promise<string | undefined>;
export const startServer: StartServerType = async (): Promise<string | undefined> => {
  try {
    let initStatusResponse;
    // Get port
    const finalPort = port();
    await server.initServer(finalPort).then((res) => {
      initStatusResponse = res;
      log.info('INIT STATUS RESPONSE: ', initStatusResponse);
    });
  } catch (e: unknown) {
    if (typeof e === 'string') {
      return e.toUpperCase(); // works, `e` narrowed to string
    }
    if (e instanceof Error) {
      return e.message; // works, `e` narrowed to Error
    }
  }
  return 'started';
};

但我总是收到“initial”作为 initStatusResponse。我知道那里存在异步问题,但我看不到哪里。

提前致谢。

【问题讨论】:

  • 根据我的经验,接受回调的函数很少返回 Promise - 所以 await gRPCserver.bindAsync..... 不太可能按您的意愿工作
  • 我同意,bindAsync 接受回调函数,因此它不返回 Promise,所以 awaiting 毫无意义。下一行代码 (return initStatus;) 将在设置 initStatus 之前立即执行。
  • 要明确 async await 与 Promises 一起使用,而不是任何模糊异步的东西
  • 另外,您将await.then() 语法混合在一起。你不能同时使用两者,完全摆脱.then()
  • @JeremyThille - 不正确,您可以将两者混合使用 - 这不是一个好习惯:p

标签: javascript typescript grpc-node


【解决方案1】:

您需要查看gRPCserver.bindAsync 的文档,但该方法似乎没有返回一个promise 对象。由于您将回调函数作为参数传递,因此增加了这种可能性。 Promise 对象不再需要回调函数(通常称为“回调地狱”)。 Here is an article 解释了在 Javascript/Typescript 中执行异步操作的不同方式之间的差异。

使用 async/await 是一个好方法。如果gRPCserver.bindAsync 没有返回一个promise,为了使用它,我们可以将它“包装”在一个promise 中。这可以使用 node.js util promisify (Documentation) 轻松完成,也可以使用 new Promise 手动完成。 This article 很好地解释了这两种方式。

【讨论】:

    猜你喜欢
    • 2019-12-04
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2019-10-29
    • 2021-03-11
    • 2019-09-04
    • 1970-01-01
    • 2020-03-24
    相关资源
    最近更新 更多