javascript - Angular:将方法作为参数传递
问题描述
我有这两种几乎相似的方法:
private firstFunction () {
this.serviceOne.methodOne().subscribe(
res => {
return resultOne = res;
},
err => {}
);
}
private secondFunction () {
this.serviceTwo.methodTwo().subscribe(
res => {
return resultTwo = res;
},
err => {}
);
}
我想写一个通用函数,像这样:
genericFunction (service ,method , result ) {
service.method().subscribe(
res => {
return result = res;
},
err => {}
);
}
因此,我想得到这样的工作:
genericFunction (serviceOne , methodOne , resultOne );
genericFunction (serviceTwo , methodTwo , resultTwo );
实际上,我找不到如何传递methodOne
和methodTwo
作为参数。有什么建议吗?
解决方案
您的代码中有几个问题。
首先,您要修改作为参数传入的字段(如建议的那样result = res
。您不能传入对字段的引用,但可以传入字段名称,并使用索引来更改字段。keyof T
将允许您以类型安全的方式传入该字段。
其次,如果您想访问服务上的方法。同样,我们可以通过传入方法名称来执行此操作,并且我们可以限制服务具有一个带有传入方法名称的方法,该方法返回一个Observable
. 的结果Observable
也可以被限制为与我们将要分配给它的字段的类型相同,以使该方法是完全类型安全的。
declare class Service1 {
method1() : Observable<number>
}
declare class Service2 {
method2() : Observable<string>
}
class MyClass {
resultOne!: number;
resultTwo!: string;
constructor() {
this.genericFunction(new Service1(), "method1", "resultOne");
this.genericFunction(new Service2(), "method2", "resultTwo");
this.genericFunction(new Service1(), "method1", "resultTwo"); // error resultTwo is a string, the method return Observable<number>
this.genericFunction(new Service2(), "method", "resultTwo"); // error method does not exit on Service2
this.genericFunction(new Service2(), "method2", "resultTwo2"); // error field does not exist on type
}
genericFunction<MethodKey extends string, ResultKey extends keyof MyClass>(service:Record<MethodKey, ()=> Observable<MyClass[ResultKey]>>, method:MethodKey, result: ResultKey){
service[method]().subscribe(
res => this[result] = res,
err => {}
);
}
}
注意我们也可以将函数作为函数传入,而不仅仅是作为名称,而是直接作为类型函数。这样做的缺点是我们要么必须使用bind
确保服务方法在调用时仍然正确this
,要么在调用时使用箭头函数(再次确保服务方法具有正确的this
)。不过这很容易出错,bind
导致函数无类型,因此我们无法检查与该字段的兼容性,并且有人可能会service.method
直接传递,直到运行时才会报告错误:
class MyClass {
resultOne!: number;
resultTwo!: string;
constructor() {
var service1 = new Service1()
var service2 = new Service2()
this.genericFunction(()=> service1.method1(), "resultOne");
this.genericFunction(()=> service2.method2(), "resultTwo");
this.genericFunction(service2.method2, "resultTwo"); // no error, depending on the implementation of method2 it might or might not work
this.genericFunction(service2.method2.bind(service2), "resultOne"); // no error, the service call will work, but we store it in an incompatible variable
this.genericFunction(()=> service1.method1(), "resultTwo");// error resultTwo is a string, the method return Observable<number>
this.genericFunction(()=> service2.method2(), "resultTwo2");// // error field does not exist on type
}
genericFunction<MethodKey extends string, ResultKey extends keyof MyClass>(method:()=> Observable<MyClass[ResultKey]>, result: ResultKey){
method().subscribe(
res => this[result] = res,
err => {}
);
}
}
推荐阅读
- postgresql - 如何更新 Postgres 表中的多个值?
- mysql - Mysqldump:将单个备份表还原到原始数据库
- python - 使用 geopandas 数据框时,紧凑的布局在 matplotlib 中不起作用?
- java - 如何从 application.yml 获取设置图?
- webassembly - 在浏览器中求解显式欧拉法的最快方法
- uwp - Windows Template Studio Caliburn.Micro 添加新页面
- python - numpy数组中的整数/浮点计算
- sql - 将 pk 自动增量链接到新表
- qpython3 - 如何在qpython3中安装downloadad包
- python - Matplotlib 颤动图矢量不垂直于轮廓