Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 可堆叠函数_Node.js_Typescript_Functional Programming_Modularity_Control Flow - Fatal编程技术网

Node.js 可堆叠函数

Node.js 可堆叠函数,node.js,typescript,functional-programming,modularity,control-flow,Node.js,Typescript,Functional Programming,Modularity,Control Flow,我正在寻找一种与库无关的方法来“堆叠”函数。我习惯使用的范例是“中间件”,其中函数中发生的某些事情可以抛出错误,并使用上下文(或req)全局来附加新属性或更改现有属性。这些想法可以在像express或type graphql这样的库中找到 我正在寻找一些不可知的方法来链接中间件,而不是依赖于这些类型的库 下面是一个我拥有的函数类型的例子 我正在努力以某种干净的方式编写函数。全局方法不是使用typescript正确键入的补充,也不是很实用 如果功能性更强的方法缺少这种“链接性”,我可以简单地拥有一

我正在寻找一种与库无关的方法来“堆叠”函数。我习惯使用的范例是“中间件”,其中函数中发生的某些事情可以抛出错误,并使用
上下文
(或
req
)全局来附加新属性或更改现有属性。这些想法可以在像
express
type graphql
这样的库中找到

我正在寻找一些不可知的方法来链接中间件,而不是依赖于这些类型的库

下面是一个我拥有的函数类型的例子

我正在努力以某种干净的方式编写函数。全局方法不是使用typescript正确键入的补充,也不是很实用

如果功能性更强的方法缺少这种“链接性”,我可以简单地拥有一系列函数,如下所示

// 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)

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

返回
这通常是能够链接方法的方式。我为您制作了一个示例,展示了同步和异步功能:

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) });
类链式操作{
构造函数(私有值:number){}
公共地址(n:编号):此{
这个值+=n;
归还这个;
}
公共减法(n:数字):此{
这个值-=n;
归还这个;
}
公共异步发送():承诺{
log(`Sending${this.value}某处`);
归还这个;
}
}
异步函数somewhere():Promise{
const firstChain=wait new chained操作(1).add(1).subtract(1).send();
等待firstChain.add(1).减法(2).send()
}
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();
抽象类Pipable{
公用管道(…函数:函数[]){
return(input:any)=>functions.reduce((chain,func:any)=>chain.then(func.bind(this)),Promise.resolve(input));
}
}
类AClass扩展了Pipable{
构造函数(私有值:number){
超级();
}
公共地址(n:编号):编号{
这个值+=n;
返回此.value;
}
公共减法(n:数字):数字{
这个值-=n;
返回此.value;
}
公共异步发送():承诺{
log(`Sending${this.value}某处`);
返回此.value;
}
}
异步函数{
const myClass=new AClass(2);
const composition=wait myClass.pipe(myClass.add、myClass.subtract、myClass.send)(2);
}
某物();

有些人不喜欢从头开始,而是从最后一个函数开始倒转。如果你想要的话,就用.reduceRight替换.reduce。如果你喜欢花哨的名字,从最后一个开始被称为组合,而不是管道。

@RobertHarvey如果没有代理,你不能以这种方式链接异步函数。这是使用此方法的一个主要缺点。不,但可以对异步函数使用连续传递样式。看,我是这本书的作者,这本书包含了两个具有可变接口的组合组合器,因此您可以以函数/应用程序/一元的方式链接异步计算。我在生产中使用异步
任务
类型,它工作得很好。如果您有上述未涉及的特定情况,我可以使其更加复杂。如果没有代理,您无法以这种方式链接异步函数。这是使用这种方法的一个主要缺点。也许用馅饼。请参阅上文,如果您需要更多详细信息,请告诉我。