typescript - 如何调用存储在变量中的异步函数?
问题描述
所以我有以下问题:
给定一个键,我将从字典中获取一个函数,该函数可以是异步函数或普通函数。但是当我将 await 关键字放在func之前时,编译器会抱怨:
TS2349:无法调用其类型缺少调用签名的表达式。类型“Promise”没有兼容的调用签名。
我该如何解决这个问题?交换机是唯一的解决方案吗?
简单的例子:
function example(aux: string){
return string
}
function async main(key, ...args): Promise<Boolean>{
dictionary = {
"example": example
}
let func = dictionary[key]
if (func instanceof Promise) { // If the function is a promise we wait
let result = await func(...args) //<-- PROBLEM HERE
} else {
let result = func(...args)
}
}
return result
完整的例子在这里:
export enum ValidatorsTypes {
EMAIL = 1,
EMAIL_IS_UNIQUE = 2
}
export function validEmail (text: any) {
const pattern = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
return pattern.test(text) || 'Invalid e-mail.'
}
export async function isEmailUnique (text: any): Promise<boolean> {
let response = await UserService.list(1, 1, { 'email': text })
// if the number of matches is 0, then is unique
return response[1] === 0
}
export async function isAnswerValid (validatorsTypes: Array<ValidatorsTypes>, ...args: any) : Promise<boolean> {
let availableValidators = {
[ValidatorsTypes.EMAIL]: validEmail,
[ValidatorsTypes.EMAIL_IS_UNIQUE]: isEmailUnique
}
let results = []
for (let rule of validatorsTypes) {
let func = availableValidators[rule]
if (func instanceof Promise) { // If the function is a promise we wait
let result = await func(...args) //<-- PROBLEM HERE
results.push(result)
} else {
results.push(func(...args))
}
}
return !results.some(v => v === false)
}
解决方案
请参阅下面的编辑以获得更简单的解决方案
问题是func instanceof Promise
检查func
它本身是否是 a Promise
,而不是是否是一个返回承诺的函数。
如果您想根据func
返回值做不同的事情,您需要instanceof Promise
检查它返回的内容。
所以这样的事情会起作用
const result = func(...args);
// const result: true | 'Invalid e-mail.' | Promise<boolean>
if (result instanceof Promise) { // we check if result is a Promise
const awaitedResult = await result; // if result is a promise we await it
// const awaitedResult: boolean
results.push(awaitedResult);
} else {
results.push(result); // otherwise we just push the value immediately
}
编辑
正如@Countingstuff 指出的那样,等待非承诺没有害处,因此我们可以通过等待任何func
返回来简化整个事情,根本不需要检查任何东西是否是承诺!
const func = availableValidators[rule];
// const func: ((text: any) => true | "Invalid e-mail.") | ((text: any) => Promise<boolean>)
const result = await func(...args);
// const result: boolean | 'Invalid e-mail.'
results.push(result);
推荐阅读
- sql - 避免在“更新或插入”SQL 中进行不必要的更新?
- c# - 响应松弛命令请求,并实际反序列化响应
- javascript - 如果选中复选框,则显示数据
- c# - 在字典中查找重复列表并打印重复列表的键
- python - 形状为 (64, 4) 的目标数组被传递为形状 (None, 3) 的输出,同时用作损失`binary_crossentropy`
- mysql - 使用phpmyadmin在我的SQL中查询删除大型数据库中的连续重复值
- javascript - 为什么 V8(一个 javascript 模块)反序列化两个 2 个不同的十六进制字符串但带来 2 个相同的对象?
- reactjs - 当 display=none 时 MaterialUI Tooltip 淡出
- sql - 结合这4个SQL函数
- matlab - 使用新变量(不同维度)创建 NetCDF 文件