#javascript #typescript #grpc-node
Вопрос:
это код для инициализации сервера 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;
};
Я пытаюсь вернуть этот статус в эту функцию:
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';
};
Но я всегда получал «начальный» в качестве ответа на запрос. Я знаю, что там есть проблема с асинхронностью, но я не вижу, где именно.
Заранее спасибо.
Комментарии:
1. по моему опыту, функция, которая выполняет обратный вызов, редко возвращает обещание, поэтому
await gRPCserver.bindAsync.....
вряд ли будет работать так, как вы хотите2. Я согласен,
bindAsync
принимает функцию обратного вызова, поэтому она не возвращает обещание, такawait
что это бессмысленно. Следующая строка кода (return initStatus;
) будет выполнена немедленно, доinitStatus
того, как будет задана.3.чтобы быть ясным
async
await
, работает с обещаниями, а не с чем-то неопределенно асинхронным4. Кроме того, вы смешиваете
await
и.then()
синтаксис вместе. Вы не можете использовать и то, и другое одновременно,.then()
полностью избавьтесь от этого.5. @JeremyThille — неправда, вы можете смешивать два — это просто не очень хорошая практика :p
Ответ №1:
Вам нужно будет проверить документацию gRPCserver.bindAsync
, но, похоже, этот метод не возвращает объект promise. Вероятность этого возрастает, поскольку вы передаете функцию обратного вызова в качестве аргумента. Объекты Promise устраняют необходимость в функциях обратного вызова (часто называемых «адом обратного вызова»). Вот статья, в которой объясняются различия между различными способами выполнения асинхронных действий в Javascript/Typescript.
Использование async/await-хороший подход. Чтобы использовать его, если gRPCserver.bindAsync
он не вернет обещание, мы можем «завернуть» его в обещание. Это можно легко сделать с помощью node.js util promisify
(Документация) или вручную с new Promise
помощью . В этой статье хорошо объясняются оба способа.