简体   繁体   English

带有回调的链函数 TypeScript

[英]Chain functions with callbacks TypeScript

After reading an article about Handling Failure by Vladimir Khorikov, I try to implement it using TypeScript.在阅读了 Vladimir Khorikov 的一篇关于处理故障的文章后,我尝试使用 TypeScript 来实现它。

The example code was written in C#, which I can understand only the idea, not the code.示例代码是用C#写的,我只能看懂思路,看不懂代码。

Here is my implementation so far.到目前为止,这是我的实现。

export class Result<T> {
  success: boolean;
  private error: string | null;
  private _value: T;

  get value(): T {
    if (!this.success) {
      throw new Error('Cannot get value of an error result.');
    }

    return this._value;
  }

  get errorMessage(): string {
    if (this.success || this.error === null) {
      throw new Error('Cannot get error message of a success result.');
    }

    return this.error;
  }

  get failure(): boolean {
    return !this.success;
  }

  private constructor(success: boolean, error: string | null, value?: T) {
    if (success && error != null) {
      throw new Error('Success result cannot have error message');
    }

    if (!success && (error === null || error.length === 0)) {
      throw new Error('Failed result must have error message');
    }

    this.success = success;
    this.error = error;
    this._value = value as T;
  }

  /**
   * Create failure result
   * @param errorMessage error message
   * @returns failureResult
   */
  static fail<T>(errorMessage: string): Result<T> {
    return new Result(false, errorMessage);
  }

  /**
   * Create success result
   * @param value
   * @returns successResult
   */
  static ok<T>(value?: T): Result<T> {
    return new Result(true, null, value);
  }

  /**
   * Combine multiple results into one result
   * @param results
   * @returns result
   */
  static combine(...results: Result<any>[]): Result<any> {
    for (let result of results) {
      if (result.failure) {
        return result;
      }
    }

    return Result.ok();
  }

  /**
   * Do things on success result
   * @param func
   * @returns result
   */
  onSuccess(func: Function): Result<T> {
    if (this.success) {
      func();
    }

    return this;
  }

  /**
   * Do things on failure result
   * @param func
   * @returns result
   */
  onFailure(func: Function): Result<T> {
    if (this.failure) {
      func();
    }

    return this;
  }

  /**
   * Do things on both success and failure result
   * @param func
   * @returns result
   */
  onBoth(func: Function): Result<T> {
    func();

    return this;
  }
}

I am struggling to implement the chain functions.我正在努力实现链功能。

In the example code, the onSuccess , onFailure , and onBoth functions are chained beautifully.在示例代码中, onSuccessonFailureonBoth函数被完美地链接在一起。

return Result.Combine(billingInfoResult, customerNameResult)
        .OnSuccess(() => _paymentGateway.ChargeCommission(billingInfoResult.Value))
        .OnSuccess(() => new Customer(customerNameResult.Value))
        .OnSuccess(
            customer => _repository.Save(customer)
                .OnFailure(() => _paymentGateway.RollbackLastTransaction())
        )
        .OnSuccess(() => _emailSender.SendGreetings(customerNameResult.Value))
        .OnBoth(result => Log(result))
        .OnBoth(result => CreateResponseMessage(result));

But in my code, it can only trigger void function.但在我的代码中,它只能触发 void function。 The function can't pass its result to the next function. function 无法将其结果传递给下一个 function。

Could you show me how to implement this?你能告诉我如何实现这个吗? Any suggestions would be appreciated.任何建议,将不胜感激。

You seem to be implementing it differently?您似乎以不同的方式实施它?

Original Code shows:原始代码显示:

public static Result OnSuccess(this Result result, Func<Result> func)
{
    if (result.Failure)
        return result;

    return func();
}

which would translate to:这将转化为:

onSuccess(fn: () => Result): Result {
    if (this.failure)
        return this;

    return fn();
}

but you have但是你有

onSuccess(func: Function): Result<T> {
    if (this.success) {
      func();
    }

    return this;
}

Following the idea of the article that was suggested by Invizi, I have come up with this solution.按照 Invizi 建议的文章的想法,我提出了这个解决方案。

 onSuccess<U>(fn: (value: T) => U): Result<U> {
    if (this.success) {
      return Result.ok(fn(this._value))
    }

    return Result.fail(this.errorMessage)
  }

This makes the chain flexible with type just like the example code.这使得链与示例代码一样具有类型灵活性。

Result.combine(Rectangle.from(5, 5), Rectangle.from(1, 1))
  .onSuccess(() => {return new User('user')}) // Create new user
  .onSuccess(user => console.log(user.name)) // Print user name

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM