我正在寻找一种与库无关的“堆栈”功能的方法。我习惯的范式是“中间件”,其中函数内发生的错误可能会引发错误,并且使用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)
有没有工具/库可以编写清晰,可链接的函数,并以可堆叠的方式将它们粘合在一起?
答案 0 :(得分:1)
返回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。如果您喜欢奇特的名称,那么从末尾开始就称为“合成”,而不是管道。