可堆叠函数

问题描述 投票:1回答:1

我正在寻找一种与库无关的方法来“堆叠”功能。我习惯的范例是“中间件”,在函数中发生的某些错误可能会引发,并且context(或req)全局变量用于附加新属性或更改现有属性。这些想法可以在expresstype-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)

是否有任何工具/库允许编写清晰且可链接的函数,并以可堆叠的方式将它们粘合在一起?

node.js typescript functional-programming modularity control-flow
1个回答
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。如果您喜欢奇特的名称,那么从末尾开始就称为“合成”,而不是管道。

© www.soinside.com 2019 - 2024. All rights reserved.