Skip to content

Commit 2c0c020

Browse files
authored
Merge pull request #205 from vplentinax/decorators
Decorators and forwarding, call/apply
2 parents ab53d84 + c0a8b2f commit 2c0c020

File tree

9 files changed

+195
-196
lines changed

9 files changed

+195
-196
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
The wrapper returned by `spy(f)` should store all arguments and then use `f.apply` to forward the call.
1+
El contenedor devuelto por `spy(f)` debe almacenar todos los argumentos y luego usar `f.apply` para reenviar la llamada.

1-js/06-advanced-functions/09-call-apply-decorators/01-spy-decorator/task.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ importance: 5
22

33
---
44

5-
# Spy decorator
5+
# Decorador espía
66

7-
Create a decorator `spy(func)` that should return a wrapper that saves all calls to function in its `calls` property.
7+
Cree un decorador `spy(func)` que debería devolver un contenedor que guarde todas las llamadas para que funcionen en su propiedad `calls`
88

9-
Every call is saved as an array of arguments.
9+
Cada llamada se guarda como un array de argumentos.
1010

11-
For instance:
11+
Por ejemplo
1212

1313
```js
1414
function work(a, b) {
15-
alert( a + b ); // work is an arbitrary function or method
15+
alert( a + b ); // work es una función o método arbitrario
1616
}
1717

1818
*!*
@@ -27,4 +27,4 @@ for (let args of work.calls) {
2727
}
2828
```
2929

30-
P.S. That decorator is sometimes useful for unit-testing. Its advanced form is `sinon.spy` in [Sinon.JS](http://sinonjs.org/) library.
30+
P.D Ese decorador a veces es útil para pruebas unitarias. Su forma avanzada es `sinon.spy` en la librería [Sinon.JS](http://sinonjs.org/).

1-js/06-advanced-functions/09-call-apply-decorators/02-delay/solution.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
The solution:
1+
Solución:
22

33
```js run demo
44
function delay(f, ms) {
@@ -11,22 +11,22 @@ function delay(f, ms) {
1111

1212
let f1000 = delay(alert, 1000);
1313

14-
f1000("test"); // shows "test" after 1000ms
14+
f1000("test"); // mostrar "test" después de 1000ms
1515
```
1616

17-
Please note how an arrow function is used here. As we know, arrow functions do not have own `this` and `arguments`, so `f.apply(this, arguments)` takes `this` and `arguments` from the wrapper.
17+
Tenga en cuenta cómo se utiliza una función de flecha aquí. Como sabemos, las funciones de flecha no tienen contextos propios `this` ni `argumentos`, por lo que `f.apply(this, arguments)` toma `this` y `arguments` del contenedor.
1818

19-
If we pass a regular function, `setTimeout` would call it without arguments and `this=window` (assuming we're in the browser).
19+
Si pasamos una función regular, `setTimeout` lo llamaría sin argumentos y `this = window` (suponiendo que estemos en el navegador).
2020

21-
We still can pass the right `this` by using an intermediate variable, but that's a little bit more cumbersome:
21+
Todavía podemos pasar el `this` correcto usando una variable intermedia, pero eso es un poco más engorroso:
2222

2323
```js
2424
function delay(f, ms) {
2525

2626
return function(...args) {
27-
let savedThis = this; // store this into an intermediate variable
27+
let savedThis = this; // almacenar esto en una variable intermedia
2828
setTimeout(function() {
29-
f.apply(savedThis, args); // use it here
29+
f.apply(savedThis, args); // úsalo aquí
3030
}, ms);
3131
};
3232

1-js/06-advanced-functions/09-call-apply-decorators/02-delay/task.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,25 @@ importance: 5
22

33
---
44

5-
# Delaying decorator
5+
# Decorador de retraso
66

7-
Create a decorator `delay(f, ms)` that delays each call of `f` by `ms` milliseconds.
7+
Cree un decorador `delay(f, ms)` que retrase cada llamada de `f` en `ms` milisegundos.
88

9-
For instance:
9+
Por ejemplo
1010

1111
```js
1212
function f(x) {
1313
alert(x);
1414
}
1515

16-
// create wrappers
16+
// crear contenedores
1717
let f1000 = delay(f, 1000);
1818
let f1500 = delay(f, 1500);
1919

20-
f1000("test"); // shows "test" after 1000ms
21-
f1500("test"); // shows "test" after 1500ms
20+
f1000("test"); // mostrar "test" después de 1000ms
21+
f1500("test"); // mostrar "test" después de 1500ms
2222
```
2323

24-
In other words, `delay(f, ms)` returns a "delayed by `ms`" variant of `f`.
24+
En otras palabras, `delay (f, ms)` devuelve una variante "Retrasada por `ms`" de`f`.
2525

26-
In the code above, `f` is a function of a single argument, but your solution should pass all arguments and the context `this`.
26+
En el código anterior, `f` es una función de un solo argumento, pero en esta solución debe pasar todos los argumentos y el contexto `this`.

1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,4 @@ function debounce(func, ms) {
99

1010
```
1111

12-
A call to `debounce` returns a wrapper. When called, it schedules the original function call after given `ms` and cancels the previous such timeout.
13-
12+
Una llamada a `debounce` devuelve un contenedor wrapper. Cuando se le llama, planifica la llamada a la función original después de los `ms` dados y cancela el tiempo de espera anterior.

1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,50 @@ importance: 5
22

33
---
44

5-
# Debounce decorator
5+
# Decorador debounce
66

7-
The result of `debounce(f, ms)` decorator is a wrapper that suspends calls to `f` until there's `ms` milliseconds of inactivity (no calls, "cooldown period"), then invokes `f` once with the latest arguments.
7+
El resultado del decorador `debounce(f, ms)` es un contenedor que suspende las llamadas a `f` hasta que haya `ms` milisegundos de inactividad (sin llamadas, "período de enfriamiento"), luego invoca `f` una vez con los últimos argumentos.
88

9-
For instance, we had a function `f` and replaced it with `f = debounce(f, 1000)`.
9+
Por ejemplo, teníamos una función `f` y la reemplazamos con `f = debounce(f, 1000)`.
1010

11-
Then if the wrapped function is called at 0ms, 200ms and 500ms, and then there are no calls, then the actual `f` will be only called once, at 1500ms. That is: after the cooldown period of 1000ms from the last call.
11+
Entonces, si la función contenedora se llama a 0ms, 200ms y 500ms, y luego no hay llamadas, entonces la 'f' real solo se llamará una vez, a 1500ms. Es decir: después del período de enfriamiento de 1000 ms desde la última llamada.
1212

1313
![](debounce.svg)
1414

15-
...And it will get the arguments of the very last call, other calls are ignored.
15+
... Y obtendrá los argumentos de la última llamada, y se ignorarán otras llamadas.
1616

17-
Here's the code for it (uses the debounce decorator from the [Lodash library](https://lodash.com/docs/4.17.15#debounce):
17+
Aquí está el código para ello (usa el decorador debounce del [Lodash library](https://lodash.com/docs/4.17.15#debounce):
1818

1919
```js
2020
let f = _.debounce(alert, 1000);
2121

2222
f("a");
2323
setTimeout( () => f("b"), 200);
2424
setTimeout( () => f("c"), 500);
25-
// debounced function waits 1000ms after the last call and then runs: alert("c")
25+
// la función debounce espera 1000 ms después de la última llamada y luego ejecuta: alert ("c")
2626
```
2727

2828

29-
Now a practical example. Let's say, the user types something, and we'd like to send a request to the server when the input is finished.
29+
Ahora un ejemplo práctico. Digamos que el usuario escribe algo y nos gustaría enviar una solicitud al servidor cuando finalice la entrada.
3030

31-
There's no point in sending the request for every character typed. Instead we'd like to wait, and then process the whole result.
31+
No tiene sentido enviar la solicitud para cada caracter escrito. En su lugar, nos gustaría esperar y luego procesar todo el resultado.
3232

33-
In a web-browser, we can setup an event handler -- a function that's called on every change of an input field. Normally, an event handler is called very often, for every typed key. But if we `debounce` it by 1000ms, then it will be only called once, after 1000ms after the last input.
33+
En un navegador web, podemos configurar un controlador de eventos, una función que se llama en cada cambio de un campo de entrada. Normalmente, se llama a un controlador de eventos con mucha frecuencia, por cada tecla escrita. Pero si le pasamos `debounce` por 1000ms, entonces solo se llamará una vez, después de 1000ms después de la última entrada.
3434

3535
```online
3636
37-
In this live example, the handler puts the result into a box below, try it:
37+
En este ejemplo en vivo, el controlador coloca el resultado en un cuadro a continuación, pruébelo:
3838
3939
[iframe border=1 src="debounce" height=200]
4040
41-
See? The second input calls the debounced function, so its content is processed after 1000ms from the last input.
41+
¿Ve? La segunda entrada llama a la función debounce, por lo que su contenido se procesa después de 1000 ms desde la última entrada.
4242
```
4343

44-
So, `debounce` is a great way to process a sequence of events: be it a sequence of key presses, mouse movements or something else.
44+
Entonces, `debounce` es una excelente manera de procesar una secuencia de eventos: ya sea una secuencia de pulsaciones de teclas, movimientos del mouse u otra cosa.
4545

4646

47-
It waits the given time after the last call, and then runs its function, that can process the result.
47+
Espera el tiempo dado después de la última llamada y luego ejecuta su función, que puede procesar el resultado.
4848

49-
The task is to implement `debounce` decorator.
49+
La tarea es implementar el decorador `debounce`.
5050

51-
Hint: that's just a few lines if you think about it :)
51+
Sugerencia: son solo algunas líneas si lo piensas :)

1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ function throttle(func, ms) {
3030
}
3131
```
3232

33-
A call to `throttle(func, ms)` returns `wrapper`.
33+
Una llamada a `throttle(func, ms)` devuelve un `wrapper`.
3434

35-
1. During the first call, the `wrapper` just runs `func` and sets the cooldown state (`isThrottled = true`).
36-
2. In this state all calls are memorized in `savedArgs/savedThis`. Please note that both the context and the arguments are equally important and should be memorized. We need them simultaneously to reproduce the call.
37-
3. After `ms` milliseconds pass, `setTimeout` triggers. The cooldown state is removed (`isThrottled = false`) and, if we had ignored calls, `wrapper` is executed with the last memorized arguments and context.
35+
1. Durante la primera llamada, el `wrapper` solo ejecuta `func` y establece el estado de enfriamiento (`isThrottled = true`).
36+
2. En este estado, todas las llamadas se memorizan en `savedArgs/savedThis`. Tenga en cuenta que tanto el contexto como los argumentos son igualmente importantes y deben memorizarse. Los necesitamos simultáneamente para reproducir la llamada.
37+
3. Después de que pasan `ms` milisegundos, se activa `setTimeout`. El estado de enfriamiento se elimina (`isThrottled = false`) y, si ignoramos las llamadas,`wrapper` se ejecuta con los últimos argumentos y contexto memorizados.
3838

39-
The 3rd step runs not `func`, but `wrapper`, because we not only need to execute `func`, but once again enter the cooldown state and setup the timeout to reset it.
39+
El tercer paso no ejecuta `func`, sino `wrapper`, porque no solo necesitamos ejecutar `func`, sino que una vez más ingresamos al estado de enfriamiento y configuramos el tiempo de espera para restablecerlo.

1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,50 @@ importance: 5
22

33
---
44

5-
# Throttle decorator
5+
# Decorador throttle
66

7-
Create a "throttling" decorator `throttle(f, ms)` -- that returns a wrapper.
7+
Crea un decorador "throttling" `throttle(f, ms)` -- que devuelve un contenedor.
88

9-
When it's called multiple times, it passes the call to `f` at maximum once per `ms` milliseconds.
9+
Cuando se llama varias veces, pasa la llamada a `f` como máximo una vez por `ms` milisegundos.
1010

11-
The difference with debounce is that it's completely different decorator:
12-
- `debounce` runs the function once after the "cooldown" period. Good for processing the final result.
13-
- `throttle` runs it not more often than given `ms` time. Good for regular updates that shouldn't be very often.
11+
La diferencia con *debounce* es que es un decorador completamente diferente:
12+
- `debounce` ejecuta la función una vez después del período de `enfriamiento`. Es bueno para procesar el resultado final.
13+
- `throttle` lo ejecuta no más de lo que se le da en el tiempo `ms`. Es bueno para actualizaciones regulares que no deberían ser muy frecuentes.
1414

15-
Let's check the real-life application to better understand that requirement and to see where it comes from.
15+
Revisemos una aplicación de la vida real para comprender mejor ese requisito y ver de dónde proviene.
1616

17-
**For instance, we want to track mouse movements.**
17+
**Por ejemplo, queremos rastrear los movimientos del mouse.**
1818

19-
In a browser we can setup a function to run at every mouse movement and get the pointer location as it moves. During an active mouse usage, this function usually runs very frequently, can be something like 100 times per second (every 10 ms).
20-
**We'd like to update some information on the web-page when the pointer moves.**
19+
En un navegador, podemos configurar una función para que se ejecute en cada movimiento del mouse y obtener la ubicación del puntero a medida que se mueve. Durante un uso activo del mouse, esta función generalmente se ejecuta con mucha frecuencia, puede ser algo así como 100 veces por segundo (cada 10 ms).
20+
**Nos gustaría actualizar cierta información en la página web cuando se mueve el puntero.**
2121

22-
...But updating function `update()` is too heavy to do it on every micro-movement. There is also no sense in updating more often than once per 100ms.
22+
...Pero la función de actualización `update()` es demasiado pesada para hacerlo en cada micro-movimiento. Tampoco tiene sentido actualizar más de una vez cada 100 ms.
2323

24-
So we'll wrap it into the decorator: use `throttle(update, 100)` as the function to run on each mouse move instead of the original `update()`. The decorator will be called often, but forward the call to `update()` at maximum once per 100ms.
24+
Entonces lo envolveremos en el decorador: use `throttle(update, 100)` como la función para ejecutar en cada movimiento del mouse en lugar del original `update()`. Se llamará al decorador con frecuencia, pero reenviará la llamada a `update()` como máximo una vez cada 100 ms.
2525

26-
Visually, it will look like this:
26+
Visualmente, se verá así:
2727

28-
1. For the first mouse movement the decorated variant immediately passes the call to `update`. That's important, the user sees our reaction to their move immediately.
29-
2. Then as the mouse moves on, until `100ms` nothing happens. The decorated variant ignores calls.
30-
3. At the end of `100ms` -- one more `update` happens with the last coordinates.
31-
4. Then, finally, the mouse stops somewhere. The decorated variant waits until `100ms` expire and then runs `update` with last coordinates. So, quite important, the final mouse coordinates are processed.
28+
1. Para el primer movimiento del mouse, el variante decorador pasa inmediatamente la llamada a `update`. Eso es importante, el usuario ve nuestra reacción a su movimiento de inmediato
29+
2. Luego, a medida que el mouse avanza, hasta `100ms` no sucede nada. La variante decorador ignora las llamadas.
30+
3. Al final de`100ms` -- ocurre un `update` más con las últimas coordenadas.
31+
4. Entonces, finalmente, el mouse se detiene en alguna parte. La variante decorador espera hasta que expire `100ms` y luego ejecuta `update` con las últimas coordenadas. Entonces, y esto es bastante importante, se procesan las coordenadas finales del mouse.
3232

33-
A code example:
33+
Un código de ejemplo:
3434

3535
```js
3636
function f(a) {
3737
console.log(a);
3838
}
3939

40-
// f1000 passes calls to f at maximum once per 1000 ms
40+
// f1000 pasa llamadas a f como máximo una vez cada 1000 ms
4141
let f1000 = throttle(f, 1000);
4242

43-
f1000(1); // shows 1
44-
f1000(2); // (throttling, 1000ms not out yet)
45-
f1000(3); // (throttling, 1000ms not out yet)
43+
f1000(1); // muestra 1
44+
f1000(2); // (throttling, 1000ms aún no)
45+
f1000(3); // (throttling, 1000ms aún no)
4646

47-
// when 1000 ms time out...
48-
// ...outputs 3, intermediate value 2 was ignored
47+
// tiempo de espera de 1000 ms ...
48+
// ...devuelve 3, el valor intermedio 2 fue ignorado
4949
```
5050

51-
P.S. Arguments and the context `this` passed to `f1000` should be passed to the original `f`.
51+
P.D Los argumentos y el contexto `this` pasado a `f1000` deben pasarse a la `f` original.

0 commit comments

Comments
 (0)