Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

315
Views
¿Cómo debo proceder con el encadenamiento de métodos en TypeScript (como lo hace Tiptap)?

Tiptap (y muchos otros editores de texto basados en ProseMirror ) tiene esta increíble API donde podemos encadenar comandos.

Por ejemplo :

 editor.chain().focus().toggleItalic().run()

Aquí, llamar a chain() devuelve todos los comandos encadenables que a su vez devuelven comandos encadenables y así es como la cadena continúa hasta que llamas a run() .

Después de llamar a run() , los comandos entre chain() y run() se ejecutan sincronizados.

Lo que es interesante (hasta donde llega mi conocimiento) es que esto no es una clase. Todo esto también se puede ampliar (incluidos los tipos) creando extensiones personalizadas para Tiptap. Vea esta extensión en negrita y sus tipos .

Fui a través de la fuente , pero no pude comprender mucho.

Realmente me gustó este patrón de diseño y me preguntaba cómo debería implementar esto en general...

Digamos, quería implementar una calculadora en este patrón. ¿Cómo puedo hacer que esta línea funcione?

 calculator.chain().setValue(10).add(3).sub(12).run() // 1

¡Gracias!

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Hay muchas formas en las que podría implementar esto, aquí hay solo una con un objeto simple. Una encapsulación de clase probablemente sería una buena idea. Siempre que mantenga sus métodos contenidos en un solo objeto, puede seguir devolviéndolo y agregándolo a la cola de devolución de llamada, que eventualmente se ejecutará en .run() y romperá el bucle.

 const calculator = { state: { value: 0 }, callbacks: [] as ((...args: any[]) => any)[], _exec: { setValue: (val: number) => (calculator.state.value = val), add: (val: number) => (calculator.state.value += val), sub: (val: number) => (calculator.state.value -= val), }, _queue: { setValue: (val: number) => { calculator.callbacks.push(() => calculator._exec.setValue(val)); return calculator._queue; }, add: (val: number) => { calculator.callbacks.push(() => calculator._exec.add(val)); return calculator._queue; }, sub: (val: number) => { calculator.callbacks.push(() => calculator._exec.sub(val)); return calculator._queue; }, run: () => { calculator.callbacks.forEach((cb) => cb()); calculator.callbacks = []; }, }, chain: () => calculator._queue, }; calculator.chain().setValue(10).add(3).sub(12).run(); console.log(calculator.state.value); // logs 1
about 4 years ago · Juan Pablo Isaza Report

0

Solo usa una class :

 class Calculator { constructor(value) { this.value = value; } run() { return this.value; } add(x) { return new Calculator(this.value + x); } sub(x) { return new Calculator(this.value - x); } log() { console.log(this.value); return this; } static withValue(v) { return new this(v); } } const calc = Calculator.withValue(10).add(3).log(); console.log(calc.sub(12).run()); console.log(calc.add(29).run());

Lo único que es importante para el encadenamiento de métodos es devolver un objeto con todos los métodos (aquí: una instancia de Calculator ) de cada uno de los métodos encadenables. También puede lograr lo mismo sin sintaxis de class :

 function calculatorWithValue(v) { return { run() { return v; }, add(x) { return calculatorWithValue(v + x); }, sub(x) { return calculatorWithValue(v - x); }, log() { console.log(v); return this; }, }; } const calc = calculatorWithValue(10).add(3).log(); console.log(calc.sub(12).run()); console.log(calc.add(29).run());

Recomiendo mantener los objetos inmutables, para permitir la creación de múltiples cadenas independientes o la bifurcación de una cadena existente; vea los ejemplos anteriores, donde el segundo resultado es 10 + 3 + 29 , no 10 + 3 - 12 + 29 .

Si desea que la ejecución sea perezosa, también es fácil:

 class Calculator { constructor(run) { this.run = run; } static withValue(v) { return new this(() => v); } add(x) { return new Calculator(() => this.run() + x); } sub(x) { return new Calculator(() => this.run() - x); } log() { return new Calculator(() => { const v = this.run(); console.log(v); return v; }); } } const calc = Calculator.withValue(10).add(3).log(); console.log(calc.sub(12).run()); console.log(calc.add(29).run());

Si desea que esto sea extensible con algún tipo de arquitectura de complemento, simplemente coloque más métodos en el prototipo o cree el objeto dinámicamente. Para TypeScript, usaría la combinación de declaraciones para modificar la interfaz de la Calculator con las firmas que proporciona su complemento.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!