Я хочу создать общую функцию, которая принимает асинхронную функцию, выполняет ее и перехватывает ошибку, если предоставленная функция сталкивается с какими-либо проблемами.
так как я пришел из фона javascript, я смог создать следующую функцию, которая делает именно это. но я хотел улучшить его с помощью дженериков и не смог этого сделать
этот код работает так, как ожидалось. но я не получаю никакого типа в своем аргументе «msg».
const botAsyncHandler = (fn:Function) => (msg: any) => {
Promise.resolve(fn(msg)).catch(error => {
console.info(error.message);
});
};
поэтому я попытался написать следующее
const botAsyncHandler = <T extends any>(fn:Function)=> (msg: T) => {
Promise.resolve(fn(msg)).catch(error => {
console.info(error.message);
console.info('here');
});
};
к сожалению, мой код не работает, и IDE по-прежнему сообщает мне, что msg имеет тип any неявно в следующем коде
bot.on('photo', botAsyncHandler(async msg => {}))
(возвращает: Parameter 'msg' implicitly has an 'any' type.
)
но выделение botAsyncHandler
показывает следующее:
botAsyncHandler<TelegramBot.Message>(fn: Function): (msg: TelegramBot.Message) => void
Что похоже на то, что я хочу. Мне любопытно знать, где я ошибаюсь
@T.J.Crowder, вся цель функции - поймать отказ от обещания и обработать его. Это всегда асинхронно. Promise.resolve(fn(arg)) был просто для согласованности. функция не должна ничего возвращать. такой пустой
Согласованность с какие?
@T.J.Crowder хороший момент. когда я это писал, функция всегда должна была возвращать обещание, и я хотел, чтобы код был понятным.
Из вашего примера использования:
bot.on('photo', botAsyncHandler(async msg => {}))
и пример JavaScript, похоже, вы пытаетесь создать функцию, которая будет возвращать функцию, которая при вызове будет вызывать оригинал, но обрабатывать ошибки из него. Самый простой способ сделать это — просто написать функцию async
с try
/catch
в ней. Версия JavaScript:
const botAsyncHandler = (fn) => async (msg) => {
try {
await fn(msg);
} catch (error) {
console.info(error.message);
}
};
добавление к нему аннотаций типа с обобщениями:
type AsyncHandler<T> = (arg: T) => {};
const botAsyncHandler = <T extends any>(fn: AsyncHandler<T>) => async (msg: T) => {
try {
await fn(msg);
} catch (error) {
console.info(error.message);
}
};
Это предполагает, что функция должна объявить один формальный параметр. Жить на детской площадке.
Но я не уверен, что добавление параметра типа даст вам что-то здесь, учитывая, что вы используете <T extends any>
.
отличный. оно работает. но другой ответ, кажется, лучше печатает
@Омид - Действительно. Если бы это был я, я бы просто предложил изменения, но...
Тип Function
бесполезен. Не используйте его. Тип параметра fn
примерно такой: (msg: T) => Promise<void>
. Или вы можете принять синхронные функции, которые возвращают void
: (msg: T) => void | Promise<void>
.
Вы можете написать:
const botAsyncHandler = <T>(fn: (msg: T) => void | Promise<void>) => async (msg: T) => {
try {
await fn(msg);
} catch (err) {
console.info(err.message);
}
};
const onString = (msg: string) => {};
const fn = botAsyncHandler(onString);
// Here, the type of 'fn' is: '(msg: string) => Promise<void>'
И я не могу проверить, но ваш код должен работать так, как ожидалось:
bot.on('photo', botAsyncHandler(async msg => {}))
Дополнительное замечание о вашей реализации JavaScript: если вы знаете, что
fn
— этоasync
, то нет смыслаPromise.resolve(fn(arg))
. Если вы не знаете, чтоfn
являетсяasync
(например, это может быть, а может и не быть), вы не будете отлавливать ошибки таким образом, если он синхронный.