我正在寻找一种与库无关的方法来“堆叠”功能。我习惯的范例是“中间件”,在函数中发生的某些错误可能会引发,并且context
(或req
)全局变量用于附加新属性或更改现有属性。这些想法可以在express
或type-graphql
之类的库中找到。
我正在寻找一种无关紧要的方式来链接中间件,而不依赖于这些类型的库。
这是我拥有的各种功能的示例。
我正在用某种简洁的方法来编写函数。全局方法不能补充使用打字稿进行正确键入的功能,并且功能不十分完善。
更具功能性的方法缺乏这种“可链接性”,在这里我可以简单地拥有如下所示的一系列功能。
// logs the start of middleware
context.utility.log(debug, ids.onLoad),
// fetches user by email submitted
context.potentialUser.fetchByEmail(SignupOnSubmitArgs),
// throws error if the user is found
context.potentialUser.errorContextPropPresent,
// checks if passowrd and reenterPassword match
context.potentialUser.signupPassword(SignupOnSubmitArgs),
// creates the user
context.user.create(SignupOnSubmitArgs, ''),
// thows error if create failed in some way
context.user.errorContextPropAbsent,
// adds user id to session
context.utility.login,
// redirects user to dashboard
context.utility.redirect(Pages2.dashboardManage)
是否有任何工具/库允许编写清晰且可链接的函数,并以可堆叠的方式将它们粘合在一起?
返回this
通常是能够链接方法的方法。我为您提供了同时显示同步和异步功能的示例:
class ChainedOperations {
constructor(private value: number){}
public add(n: number): this {
this.value += n;
return this;
}
public subtract(n: number): this {
this.value -= n;
return this;
}
public async send(): Promise<this> {
console.log(`Sending ${this.value} somewhere`);
return this;
}
}
async function somewhereElse(): Promise<void> {
const firstChain = await new ChainedOperations(1).add(1).subtract(1).send();
await firstChain.add(1).subtract(2).send()
}
somewhereElse().catch(e => { throw new Error(e) });
为了更好地处理异步功能,您可以在链接的地方使用管道模式,也可以等待最终结果并将其传递给下一个家伙:
abstract class Pipable {
public pipe(...functions: Function[]) {
return (input: any) => functions.reduce((chain, func: any) => chain.then(func.bind(this)), Promise.resolve(input));
}
}
class AClass extends Pipable {
constructor(private value: number){
super();
}
public add(n: number): number {
this.value += n;
return this.value;
}
public subtract(n: number): number {
this.value -= n;
return this.value;
}
public async send(): Promise<number> {
console.log(`Sending ${this.value} somewhere`);
return this.value;
}
}
async function Something(){
const myClass = new AClass(2);
const composition = await myClass.pipe(myClass.add, myClass.subtract, myClass.send)(2);
}
Something();
有些人不喜欢从头开始,而是从最后一个功能开始倒退。如果需要,只需将.reduce替换为.reduceRight。如果您喜欢奇特的名称,那么从末尾开始就称为“合成”,而不是管道。