Есть ли способ для набора методов класса узнать, когда вызов завершен? - PullRequest
0 голосов
/ 09 декабря 2018

В библиотеках, подобных lodash, реализован метод .chain(), в котором каждый последующий цепочечный метод будет возвращать ссылку на this, позволяя сделать цепочку возможной.Недостатком является то, что в конце цепочки для разрешения набора функций необходимо вызвать метод .value() для возврата полученного значения.

Мне любопытно, есть ли здесь возможность узнатьцепочка заканчивается без функции резолвера?Есть ли способ для каждого отдельного метода узнать, есть ли последующий вызов, и если нет, вернуть полученное значение?

Вот пример:

enum Direction {
    LEFT = 'LEFT',
    UP = 'UP',
    DOWN = 'DOWN',
    RIGHT = 'RIGHT',
}

class Move {
    movement: Direction[];
    constructor () {
        this.movement = []
    }
    left () {
        this.movement.push(Direction.LEFT)
        return this
    }
    right () {
        this.movement.push(Direction.RIGHT)
        return this
    }
    up () {
        this.movement.push(Direction.UP)
        return this
    }
    down () {
        this.movement.push(Direction.DOWN)
        return this
    }
    resolve () {
        return this.movement;
    }
}

const m = new Move()

const code = m
    .up()
    .up()
    .down()
    .down()
    .left()
    .right()
    .left()
    .right()
    .resolve();

console.log(code)

Я ищу способимеют следующее значение и все равно имеют то же значение, что и m выше, каким-либо образом изменяя каждый метод.

const code = m
    .up()
    .up()
    .down()
    .down()
    .left()
    .right()
    .left()
    .right();

Ответы [ 2 ]

0 голосов
/ 09 декабря 2018

Однако существует шаблон, который допускает такое завершение:

input.pipe(up(), up(), left());

Делая функции автономными и «обвязывая» их, вы знаете, что цепочка заканчивается внутри pipe (обратите внимание, что они должныбыть функциями высшего порядка).Этот шаблон используется, например, rxjs, хотя там они вообще не заботятся о прекращении цепочки.Причина, по которой это делается там (что тоже хорошо), заключается в том, что она дает вам легко расширяемую систему операторов, которая может быть потрясена деревом.

Точно так же вы можете вернуться к точечной цепочке (если вы действительно этого хотите)), просто обернув цепочку:

input.chain(chain => chain.left().up());

Метод chain может запустить предоставленную ему функцию и знает, что в конце этого цепочка завершается.Таким образом, предполагая, что ваши функции возвращают объект с помощью метода value, pipe / chain может просто неявно вызвать его в конце:

chain(chainer: (obj: MyObj) => MyObj) { 
  return chainer(this).value(); 
}

Конечно, по сути это переносит бремя вызоваvalue в конце к вызову цепочки в начале.


Еще одно замечание: я бы, вероятно, не реализовал этот класс, чтобы иметь это изменяемое состояние, но, если вы используете цепочку, вместо этого идите по пути использования неизменяемого объекта и каждый такой оператор возвращает новый объект.,Это делает поведение цепочки более предсказуемым и разумным, так как вы не рискуете применить последовательность цепочек дважды и т. Д.

0 голосов
/ 09 декабря 2018

Есть ли способ для каждого отдельного метода узнать, есть ли последующий вызов, и если нет, вернуть полученное значение?

Нет.Вы можете использовать тайм-аут, который по существу опрос и ненадежный.

Реальный мир

Необходим метод разрешения не новый, например, Underscore использует пару chain и value: https://underscorejs.org/#chaining

...