{
    "componentChunkName": "component---node-modules-gatsby-theme-try-ghost-src-templates-post-js",
    "path": "/js-algoritmos-y-estructuras-de-datos-big-o/",
    "result": {"data":{"ghostPost":{"id":"Ghost__Post__5c1a01ea2dd6610fd828cad3","title":"JS Algoritmos y estructuras de datos I: Big O","slug":"js-algoritmos-y-estructuras-de-datos-big-o","featured":false,"feature_image":"https://jlgarcia.fulldev.ninja/assets/images/2018/12/unordered-3192273_640.png","excerpt":"Hablemos de algoritmos, eficiencia y esas cosas, es decir, hablemos de cosas\n'chungas'.\nPara medir la eficiencia de los algoritmos no usamos el tiempo propiamente dicho\n(como podríamos pensar en un primer momento), si lo midiéramos mediante algo\ntemporal, como segundos, milisegundos o cosas así los datos no serían fiables,\nya que dependen del hardware y de lo que esté haciendo en ese momento el\nordenador.\nEn su lugar usamos 2 tipos de medidas:\n\n * Time complexity (complejidad temporal).\n * Space","custom_excerpt":null,"visibility":"public","created_at_pretty":"19 Dec 2018","published_at_pretty":"4 Nov 2018","updated_at_pretty":"19 Jan 2021","created_at":"2018-12-19T09:31:38.000+01:00","published_at":"2018-11-04T09:31:00.000+01:00","updated_at":"2021-01-19T20:56:02.000+01:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"Perfil.jpg","publicURL":"/static/b0de6281fb28a266510b3b09b9243e5a/Perfil.jpg","imageMeta":{"width":307,"height":307},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUDBAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGzw6zC6zHn+cLYP//EAB0QAAICAQUAAAAAAAAAAAAAAAEDAAIEEyEiIzL/2gAIAQEAAQUCifca8KgcKWVfUpkHsG5pxX//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAdEAACAgEFAAAAAAAAAAAAAAAAARARcQISIUFR/9oACAEBAAY/AhU88xkb7N06a8P/xAAcEAEAAwEAAwEAAAAAAAAAAAABABEhMUFRYXH/2gAIAQEAAT8hR2pq40aqb+xIAeXibhW9JXr8joF4TBcSNe0//9oADAMBAAIAAwAAABDzDwD/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAcEAEAAgIDAQAAAAAAAAAAAAABABEhUTFhcfD/2gAIAQEAAT8QyItrELaTlatLwU63MvEW6vUNdy4LZQDn7iVApV9VLtANdWwKkuYq4Er1VZ//2Q==","aspectRatio":1,"src":"/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg","srcSet":"/static/b0de6281fb28a266510b3b09b9243e5a/f340b/Perfil.jpg 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/22d64/Perfil.jpg 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/aa249/Perfil.jpg 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/0dc33/Perfil.jpg 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/60667/Perfil.jpg 307w","srcWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp","srcSetWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/59cda/Perfil.webp 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/7da75/Perfil.webp 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f282e/Perfil.webp 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/a7b21/Perfil.webp 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f59af/Perfil.webp 307w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"algoritmos","url":"https://jlgarcia.fulldev.ninja/tag/algoritmos/","name":"algoritmos","visibility":"public","feature_image":null,"description":null,"meta_title":null,"meta_description":null,"featureImageSharp":null},"tags":[{"slug":"algoritmos","url":"https://jlgarcia.fulldev.ninja/tag/algoritmos/","name":"algoritmos","visibility":"public","feature_image":null,"description":null,"meta_title":null,"meta_description":null,"featureImageSharp":null}],"plaintext":"Hablemos de algoritmos, eficiencia y esas cosas, es decir, hablemos de cosas\n'chungas'.\nPara medir la eficiencia de los algoritmos no usamos el tiempo propiamente dicho\n(como podríamos pensar en un primer momento), si lo midiéramos mediante algo\ntemporal, como segundos, milisegundos o cosas así los datos no serían fiables,\nya que dependen del hardware y de lo que esté haciendo en ese momento el\nordenador.\nEn su lugar usamos 2 tipos de medidas:\n\n * Time complexity (complejidad temporal).\n * Space complexity (complejidad espacial) o también lo podríamos llamar \n   Auxiliary Space complexity (luego hablaremos de esto).\n\nY para cualquiera de estos tipos de medida usamos lo que se conoce como Big O\nnotation o notación de Landau. No vamos a entrar en la matemática específica de\nesto, si queréis saber más tenéis más información aquí\n[https://es.wikipedia.org/wiki/Notaci%C3%B3n_de_Landau]. En nuestro caso valdrá\ncon que tengamos este diagrama como referencia\n\n\n\nSiendo O(1) lo mejor y O(n^2) lo peor. Con esto como base empecemos.\n\nTIME COMPLEXITY\nAl contrario de lo que indica su nombre no es una regla de medida temporal, lo\nque hace es medir la efeciencia basándose en el número de operaciones simples \nque realiza la función, entendiendo por operaciones simples: =, +, -, *, /, %,\n<, >.\n\nVeamoslo mejor con algunos ejemplos simples:\n\nfunction addUpTo(n) {\n    let total = 0;\n    for (let i= 0; i <= n; i++) {\n        total += i;\n    }\n\n    return total;\n}\n\n\nVeamos cuantas operaciones tenemos aquí:\n\n 1. let total=0: Primera asignación que ocurre solo 1 vez.\n 2. let i=0: Segunda asignación que ocurre solo 1 vez.\n    3 y 4. i <= n: Que se divide en 2 comparaciones 1 por el < y otra por el = y\n    esto se haría n veces.\n    5 y 6. i++: Esto es una suma y una asignación a i que se produce a su vez n \n    veces.\n    7 y 8. total += i: Y esto es igual que el anterior una suma y una asignación\n    que se produce n veces.\n\nEn este caso tenemos 2 operaciones simples que se producen solo 1 vez y luego 6\noperaciones que se producen n veces, es decir, que dependen de n, por lo tanto\n¿cual creéis que será el TIME COMPLEXITY en este caso? Pensemos que son todo\noperaciones simples pero que dependen de n, por lo que en este caso nuestro\nvalor será O(n).\n\nVayamos ahora con otro ejemplo:\n\nfunction addUpToV2(n) {\n    return n * (n + 1) / 2;\n}\n\n\nEs la misma función, es decir, hace lo mismo, nos devuelve la suma de todos los\nvalores menores que n incluido n. Veamos las operaciones:\n\n 1. n+1: Operación suma que se produce 1 vez.\n 2. n * (resultado de lo anterior): Multiplicación del resultado anterior que se\n    produce 1 vez.\n 3. resultado anterior/2: División del resultado anterior que se produce solo 1\n    vez.\n\nEn este caso tenemos solo 3 operaciones pero además estas operaciones solo se\nproducen una vez, es decir, no dependen de n, por lo tanto, en este caso el\nvalor sería O(1) puesto que pasemos el número que pasemos a n siempre es\nconstante la cantidad de operaciones que se realizarán.\n\nOtro ejemplo:\n\nfunction countUpAndDown(n){\n    console.log(\"Hacia arriba...\");\n   \n    for (let i = 0; i < n; i++) {\n      console.log(i);\n    }\n\n    console.log(\"En la cima \\n Bajando...\");\n    for (let j = n -1; j >= 0; j--) {\n        console.log(j);\n    }\n    console.log(\"Bajamos!!\");\n  \n}\n\n\nEn este caso tenemos 2 bucles que como ya hemos visto cada una sería O(n), es\ndecir, O(2n). Es 2n porque depende 2 veces de n, pero al medir la complejidad\nsiempre ignoramos los valores numéricos constantes por lo que volvemos a tener\nuna función con un valor de 0(n).\n\nY ahora vamos con el último ejemplo con las medidas simples de medida (de\nmomento no entramos a las medidas logarítmicas).\n\nfunction printAllPairs (n){\n    for (let i = 0; i < n; i++) {\n        for (let j = 0; j < n; j++) {\n            console.log(i,j);\n        }\n    }\n}\n\n\nAquí tenemos otro par de bucles, pero en este caso son 2 bucles anidados, es\ndecir, uno dentro de otro, por lo que sería un n veces del bucle interior, por\ncada n veces del bucle superior, es decir, n*n o n^2, resumiendo en este caso\ntendríamos la peor medida de todas O(n^2).\n\nHasta aquí de momento en cuanto al Time Complexity, más adelante volveremos a\nello, ahora vamos a por el Space Complexity\n\nSPACE COMPLEXITY\nCuando hablamos de la complejidad espacial, nos referimos a cuanta memoria\nnecesitaremos para ejecutar nuestra función. Al igual que con la time complexity\n, se usa para medir O, lo único que en este caso lo que diferenciamos será:\n\n * Valores primitivos: number, boolean, undefined y null. Estos valores son\n   siempre constantes en cuanto a su tamaño por lo que ocuparán O(1).\n * Objetos y arrays: Que en este caso se miden en O(n) siendo n la cantidad de\n   keys en los objetos y siendo n el tamaño de array.\n\nEn este caso la diferenciación es simple, si no tiene arrays u objetos será O(1)\n, si tiene n arrays u objetos O(n) y si tiene arrays u objetos anidados entre sí\nsería O(n^x) siendo x la cantidad de anidación que tengamos, es decir, si\ntenemos un array de 3 dimensiones tendremos un O(n^3), si tenemos uno de 2 \nO(n^2).\n\nEsto en cuanto a la parte simple del space complexity y del time complexity,\nevidentemente todo esto tiene algo más de chicha cuando entramos en los\nresultados intermedios de la gráfica (si, esos que contienen logaritmos).\nHagamos un repaso de los logaritmos\n\nLOGARITMOS\nHablemos ahora de los logaritmos, puesto que aunque no los hayamos visto todavía\nen algún ejemplo si que forman parte de las mediciones de eficiencia de los\nalgoritmos. Si os fijáis en la gráfica inicial están presentes en las mediciones\nintermedias.\n\nPues veamos, ¿qué es un logaritmo? Para ponerlo simple es lo contrario que un\nexponente, es decir, ¿cuál es el resultado de 2^4? (2 elevado a 4)?\n16\nPor lo que entonces sería:\n\n\nUna definición más específica sería:\nUn logaritmo es la cantidad de veces que tengo que dividir un número por 2 (si\nes de base 2) hasta tener un valor menor o igual a 1. En nuestro caso serían 4 \nlas veces que tenemos que dividir 16:\n\n 1. 16 / 2 = 8\n 2. 8 / 2 = 4\n 3. 4 / 2 = 2\n 4. 2 / 2 = 1\n\nY a la hora de hablar de logaritmos, por defecto siempre hablamos de logaritmos\nbase 2, por lo que lo podemos omitir (y así es como lo vemos en las gráficas).\n\nBueno y hasta aquí lo básico, nos vemos en el siguiente, un abrazooorrrrr.","html":"<!--kg-card-begin: markdown--><p>Hablemos de algoritmos, eficiencia y esas cosas, es decir, hablemos de cosas 'chungas'.<br>\nPara medir la eficiencia de los algoritmos no usamos el tiempo propiamente dicho (como podríamos pensar en un primer momento), si lo midiéramos mediante algo temporal, como segundos, milisegundos o cosas así los datos no serían fiables, ya que dependen del hardware y de lo que esté haciendo en ese momento el ordenador.<br>\nEn su lugar usamos 2 tipos de medidas:</p>\n<ul>\n<li><strong>Time complexity (complejidad temporal)</strong>.</li>\n<li><strong>Space complexity (complejidad espacial)</strong> o también lo podríamos llamar <strong>Auxiliary Space complexity</strong> (luego hablaremos de esto).</li>\n</ul>\n<p>Y para cualquiera de estos tipos de medida usamos lo que se conoce como <strong>Big O notation</strong> o <strong>notación de Landau</strong>. No vamos a entrar en la matemática específica de esto, si queréis saber más tenéis más información <a href=\"https://es.wikipedia.org/wiki/Notaci%C3%B3n_de_Landau\">aquí</a>. En nuestro caso valdrá con que tengamos este diagrama como referencia</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/12/Capture.JPG\" alt=\"Capture\"></p>\n<p>Siendo <strong>O(1)</strong> lo mejor y <strong>O(n^2)</strong> lo peor. Con esto como base empecemos.</p>\n<h3 id=\"timecomplexity\">TIME COMPLEXITY</h3>\n<p>Al contrario de lo que indica su nombre no es una regla de medida temporal, lo que hace es medir la efeciencia basándose en el <strong>número de operaciones simples</strong> que realiza la función, entendiendo por operaciones simples: <strong>=, +, -, *, /, %, &lt;, &gt;</strong>.</p>\n<p>Veamoslo mejor con algunos ejemplos simples:</p>\n<pre><code class=\"language-javascript\">function addUpTo(n) {\n    let total = 0;\n    for (let i= 0; i &lt;= n; i++) {\n        total += i;\n    }\n\n    return total;\n}\n</code></pre>\n<p>Veamos cuantas operaciones tenemos aquí:</p>\n<ol>\n<li><strong>let total=0</strong>: Primera asignación que ocurre solo 1 vez.</li>\n<li><strong>let i=0</strong>: Segunda asignación que ocurre solo 1 vez.<br>\n3 y 4. <strong>i &lt;= n</strong>: Que se divide en 2 comparaciones 1 por el <strong>&lt;</strong> y otra por el <strong>=</strong> y esto se haría <strong>n</strong> veces.<br>\n5 y 6. <strong>i++</strong>: Esto es una suma y una asignación a i que se produce a su vez <strong>n</strong> veces.<br>\n7 y 8. <strong>total += i</strong>: Y esto es igual que el anterior una suma y una asignación que se produce <strong>n</strong> veces.</li>\n</ol>\n<p>En este caso tenemos <strong>2 operaciones simples que se producen solo 1 vez</strong> y luego <strong>6 operaciones que se producen n veces</strong>, es decir, que dependen de <strong>n</strong>, por lo tanto ¿cual creéis que será el <strong>TIME COMPLEXITY</strong> en este caso? Pensemos que son todo operaciones simples pero que dependen de <strong>n</strong>, por lo que en este caso nuestro valor será <strong>O(n)</strong>.</p>\n<p>Vayamos ahora con otro ejemplo:</p>\n<pre><code class=\"language-javascript\">function addUpToV2(n) {\n    return n * (n + 1) / 2;\n}\n</code></pre>\n<p>Es la misma función, es decir, hace lo mismo, nos devuelve la suma de todos los valores menores que n incluido n. Veamos las operaciones:</p>\n<ol>\n<li><strong>n+1</strong>: Operación suma que se produce 1 vez.</li>\n<li><strong>n * (resultado de lo anterior)</strong>: Multiplicación del resultado anterior que se produce 1 vez.</li>\n<li><strong>resultado anterior/2</strong>: División del resultado anterior que se produce solo 1 vez.</li>\n</ol>\n<p>En este caso tenemos solo 3 operaciones pero además estas operaciones <strong>solo se producen una vez</strong>, es decir, <strong>no dependen de n</strong>, por lo tanto, en este caso el valor sería O(1) puesto que pasemos el número que pasemos a n siempre es constante la cantidad de operaciones que se realizarán.</p>\n<p>Otro ejemplo:</p>\n<pre><code class=\"language-javascript\">function countUpAndDown(n){\n    console.log(&quot;Hacia arriba...&quot;);\n   \n    for (let i = 0; i &lt; n; i++) {\n      console.log(i);\n    }\n\n    console.log(&quot;En la cima \\n Bajando...&quot;);\n    for (let j = n -1; j &gt;= 0; j--) {\n        console.log(j);\n    }\n    console.log(&quot;Bajamos!!&quot;);\n  \n}\n</code></pre>\n<p>En este caso tenemos 2 bucles que como ya hemos visto cada una sería <strong>O(n)</strong>, es decir, <strong>O(2n)</strong>. Es <strong>2n</strong> porque depende 2 veces de n, pero al medir la complejidad siempre <strong>ignoramos los valores numéricos constantes</strong> por lo que volvemos a tener una función con un valor de <strong>0(n)</strong>.</p>\n<p>Y ahora vamos con el último ejemplo con las medidas simples de medida (de momento no entramos a las medidas logarítmicas).</p>\n<pre><code class=\"language-javascript\">function printAllPairs (n){\n    for (let i = 0; i &lt; n; i++) {\n        for (let j = 0; j &lt; n; j++) {\n            console.log(i,j);\n        }\n    }\n}\n</code></pre>\n<p>Aquí tenemos otro par de bucles, pero en este caso son 2 bucles anidados, es decir, uno dentro de otro, por lo que sería un <strong>n</strong> veces del bucle interior, por cada <strong>n</strong> veces del bucle superior, es decir, <strong>n*n</strong> o <strong>n^2</strong>, resumiendo en este caso tendríamos la peor medida de todas <strong>O(n^2)</strong>.</p>\n<p>Hasta aquí de momento en cuanto al <strong>Time Complexity</strong>, más adelante volveremos a ello, ahora vamos a por el <strong>Space Complexity</strong></p>\n<h3 id=\"spacecomplexity\">SPACE COMPLEXITY</h3>\n<p>Cuando hablamos de la <strong>complejidad espacial</strong>, nos referimos a cuanta memoria necesitaremos para ejecutar nuestra función. Al igual que con la <strong>time complexity</strong>, se usa para medir <strong>O</strong>, lo único que en este caso lo que diferenciamos será:</p>\n<ul>\n<li><strong>Valores primitivos</strong>: number, boolean, undefined y null. Estos valores son siempre constantes en cuanto a su tamaño por lo que ocuparán <strong>O(1)</strong>.</li>\n<li><strong>Objetos y arrays</strong>: Que en este caso se miden en O(n) siendo <strong>n la cantidad de keys en los objetos</strong> y <strong>siendo n el tamaño de array</strong>.</li>\n</ul>\n<p>En este caso la diferenciación es simple, si no tiene arrays u objetos será <strong>O(1)</strong>, si tiene n arrays u objetos <strong>O(n)</strong> y si tiene arrays u objetos anidados entre sí sería <strong>O(n^x)</strong> siendo <strong>x</strong> la cantidad de anidación que tengamos, es decir, si tenemos un array de 3 dimensiones tendremos un <strong>O(n^3)</strong>, si tenemos uno de 2 <strong>O(n^2)</strong>.</p>\n<p>Esto en cuanto a la parte simple del <strong>space complexity</strong> y del <strong>time complexity</strong>, evidentemente todo esto tiene algo más de chicha cuando entramos en los resultados intermedios de la gráfica (si, esos que contienen logaritmos). Hagamos un repaso de los logaritmos</p>\n<h3 id=\"logaritmos\">LOGARITMOS</h3>\n<p>Hablemos ahora de los logaritmos, puesto que aunque no los hayamos visto todavía en algún ejemplo si que forman parte de las mediciones de eficiencia de los algoritmos. Si os fijáis en la gráfica inicial están presentes en las mediciones intermedias.</p>\n<p>Pues veamos, ¿qué es un logaritmo? Para ponerlo simple es lo contrario que un exponente, es decir, ¿cuál es el resultado de 2^4? (2 elevado a 4)?<br>\n<strong>16</strong><br>\nPor lo que entonces sería:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/12/Capture-7.JPG\" alt=\"Capture-7\"></p>\n<p>Una definición más específica sería:<br>\nUn logaritmo es la cantidad de veces que tengo que dividir un número por 2 (si es de base 2) hasta tener un valor menor o igual a 1. En nuestro caso serían <strong>4</strong> las veces que tenemos que dividir 16:</p>\n<ol>\n<li>16 / 2 = 8</li>\n<li>8 / 2 = 4</li>\n<li>4 / 2 = 2</li>\n<li>2 / 2 = 1</li>\n</ol>\n<p>Y a la hora de hablar de logaritmos, por defecto siempre hablamos de logaritmos base 2, por lo que lo podemos omitir (y así es como lo vemos en las gráficas).</p>\n<p>Bueno y hasta aquí lo básico, nos vemos en el siguiente, un abrazooorrrrr.</p>\n<!--kg-card-end: markdown-->","url":"https://jlgarcia.fulldev.ninja/js-algoritmos-y-estructuras-de-datos-big-o/","canonical_url":null,"uuid":"1ff78f4b-a1d5-4b35-a3c7-2b64cd29e3a9","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"5c1a01ea2dd6610fd828cad3","reading_time":5,"send_email_when_published":false,"email_subject":null,"childHtmlRehype":{"html":"<!--kg-card-begin: markdown--><p>Hablemos de algoritmos, eficiencia y esas cosas, es decir, hablemos de cosas 'chungas'.<br>\nPara medir la eficiencia de los algoritmos no usamos el tiempo propiamente dicho (como podríamos pensar en un primer momento), si lo midiéramos mediante algo temporal, como segundos, milisegundos o cosas así los datos no serían fiables, ya que dependen del hardware y de lo que esté haciendo en ese momento el ordenador.<br>\nEn su lugar usamos 2 tipos de medidas:</p>\n<ul>\n<li><strong>Time complexity (complejidad temporal)</strong>.</li>\n<li><strong>Space complexity (complejidad espacial)</strong> o también lo podríamos llamar <strong>Auxiliary Space complexity</strong> (luego hablaremos de esto).</li>\n</ul>\n<p>Y para cualquiera de estos tipos de medida usamos lo que se conoce como <strong>Big O notation</strong> o <strong>notación de Landau</strong>. No vamos a entrar en la matemática específica de esto, si queréis saber más tenéis más información <a href=\"https://es.wikipedia.org/wiki/Notaci%C3%B3n_de_Landau\">aquí</a>. En nuestro caso valdrá con que tengamos este diagrama como referencia</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/12/Capture.JPG\" alt=\"Capture\"></p>\n<p>Siendo <strong>O(1)</strong> lo mejor y <strong>O(n^2)</strong> lo peor. Con esto como base empecemos.</p>\n<h3 id=\"timecomplexity\">TIME COMPLEXITY</h3>\n<p>Al contrario de lo que indica su nombre no es una regla de medida temporal, lo que hace es medir la efeciencia basándose en el <strong>número de operaciones simples</strong> que realiza la función, entendiendo por operaciones simples: <strong>=, +, -, *, /, %, &#x3C;, ></strong>.</p>\n<p>Veamoslo mejor con algunos ejemplos simples:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token function\">addUpTo</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">let</span> total <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">let</span> i<span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&#x3C;=</span> n<span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        total <span class=\"token operator\">+=</span> i<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">return</span> total<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n</code></pre></div>\n<p>Veamos cuantas operaciones tenemos aquí:</p>\n<ol>\n<li><strong>let total=0</strong>: Primera asignación que ocurre solo 1 vez.</li>\n<li><strong>let i=0</strong>: Segunda asignación que ocurre solo 1 vez.<br>\n3 y 4. <strong>i &#x3C;= n</strong>: Que se divide en 2 comparaciones 1 por el <strong>&#x3C;</strong> y otra por el <strong>=</strong> y esto se haría <strong>n</strong> veces.<br>\n5 y 6. <strong>i++</strong>: Esto es una suma y una asignación a i que se produce a su vez <strong>n</strong> veces.<br>\n7 y 8. <strong>total += i</strong>: Y esto es igual que el anterior una suma y una asignación que se produce <strong>n</strong> veces.</li>\n</ol>\n<p>En este caso tenemos <strong>2 operaciones simples que se producen solo 1 vez</strong> y luego <strong>6 operaciones que se producen n veces</strong>, es decir, que dependen de <strong>n</strong>, por lo tanto ¿cual creéis que será el <strong>TIME COMPLEXITY</strong> en este caso? Pensemos que son todo operaciones simples pero que dependen de <strong>n</strong>, por lo que en este caso nuestro valor será <strong>O(n)</strong>.</p>\n<p>Vayamos ahora con otro ejemplo:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token function\">addUpToV2</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> n <span class=\"token operator\">*</span> <span class=\"token punctuation\">(</span>n <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">/</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n</code></pre></div>\n<p>Es la misma función, es decir, hace lo mismo, nos devuelve la suma de todos los valores menores que n incluido n. Veamos las operaciones:</p>\n<ol>\n<li><strong>n+1</strong>: Operación suma que se produce 1 vez.</li>\n<li><strong>n * (resultado de lo anterior)</strong>: Multiplicación del resultado anterior que se produce 1 vez.</li>\n<li><strong>resultado anterior/2</strong>: División del resultado anterior que se produce solo 1 vez.</li>\n</ol>\n<p>En este caso tenemos solo 3 operaciones pero además estas operaciones <strong>solo se producen una vez</strong>, es decir, <strong>no dependen de n</strong>, por lo tanto, en este caso el valor sería O(1) puesto que pasemos el número que pasemos a n siempre es constante la cantidad de operaciones que se realizarán.</p>\n<p>Otro ejemplo:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token function\">countUpAndDown</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n    console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Hacia arriba...\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n   \n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">let</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&#x3C;</span> n<span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"En la cima \\n Bajando...\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">let</span> j <span class=\"token operator\">=</span> n <span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">;</span> j <span class=\"token operator\">>=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> j<span class=\"token operator\">--</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>j<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Bajamos!!\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  \n<span class=\"token punctuation\">}</span>\n</code></pre></div>\n<p>En este caso tenemos 2 bucles que como ya hemos visto cada una sería <strong>O(n)</strong>, es decir, <strong>O(2n)</strong>. Es <strong>2n</strong> porque depende 2 veces de n, pero al medir la complejidad siempre <strong>ignoramos los valores numéricos constantes</strong> por lo que volvemos a tener una función con un valor de <strong>0(n)</strong>.</p>\n<p>Y ahora vamos con el último ejemplo con las medidas simples de medida (de momento no entramos a las medidas logarítmicas).</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token function\">printAllPairs</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">n</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">let</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&#x3C;</span> n<span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">let</span> j <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> j <span class=\"token operator\">&#x3C;</span> n<span class=\"token punctuation\">;</span> j<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">,</span>j<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n</code></pre></div>\n<p>Aquí tenemos otro par de bucles, pero en este caso son 2 bucles anidados, es decir, uno dentro de otro, por lo que sería un <strong>n</strong> veces del bucle interior, por cada <strong>n</strong> veces del bucle superior, es decir, <strong>n*n</strong> o <strong>n^2</strong>, resumiendo en este caso tendríamos la peor medida de todas <strong>O(n^2)</strong>.</p>\n<p>Hasta aquí de momento en cuanto al <strong>Time Complexity</strong>, más adelante volveremos a ello, ahora vamos a por el <strong>Space Complexity</strong></p>\n<h3 id=\"spacecomplexity\">SPACE COMPLEXITY</h3>\n<p>Cuando hablamos de la <strong>complejidad espacial</strong>, nos referimos a cuanta memoria necesitaremos para ejecutar nuestra función. Al igual que con la <strong>time complexity</strong>, se usa para medir <strong>O</strong>, lo único que en este caso lo que diferenciamos será:</p>\n<ul>\n<li><strong>Valores primitivos</strong>: number, boolean, undefined y null. Estos valores son siempre constantes en cuanto a su tamaño por lo que ocuparán <strong>O(1)</strong>.</li>\n<li><strong>Objetos y arrays</strong>: Que en este caso se miden en O(n) siendo <strong>n la cantidad de keys en los objetos</strong> y <strong>siendo n el tamaño de array</strong>.</li>\n</ul>\n<p>En este caso la diferenciación es simple, si no tiene arrays u objetos será <strong>O(1)</strong>, si tiene n arrays u objetos <strong>O(n)</strong> y si tiene arrays u objetos anidados entre sí sería <strong>O(n^x)</strong> siendo <strong>x</strong> la cantidad de anidación que tengamos, es decir, si tenemos un array de 3 dimensiones tendremos un <strong>O(n^3)</strong>, si tenemos uno de 2 <strong>O(n^2)</strong>.</p>\n<p>Esto en cuanto a la parte simple del <strong>space complexity</strong> y del <strong>time complexity</strong>, evidentemente todo esto tiene algo más de chicha cuando entramos en los resultados intermedios de la gráfica (si, esos que contienen logaritmos). Hagamos un repaso de los logaritmos</p>\n<h3 id=\"logaritmos\">LOGARITMOS</h3>\n<p>Hablemos ahora de los logaritmos, puesto que aunque no los hayamos visto todavía en algún ejemplo si que forman parte de las mediciones de eficiencia de los algoritmos. Si os fijáis en la gráfica inicial están presentes en las mediciones intermedias.</p>\n<p>Pues veamos, ¿qué es un logaritmo? Para ponerlo simple es lo contrario que un exponente, es decir, ¿cuál es el resultado de 2^4? (2 elevado a 4)?<br>\n<strong>16</strong><br>\nPor lo que entonces sería:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/12/Capture-7.JPG\" alt=\"Capture-7\"></p>\n<p>Una definición más específica sería:<br>\nUn logaritmo es la cantidad de veces que tengo que dividir un número por 2 (si es de base 2) hasta tener un valor menor o igual a 1. En nuestro caso serían <strong>4</strong> las veces que tenemos que dividir 16:</p>\n<ol>\n<li>16 / 2 = 8</li>\n<li>8 / 2 = 4</li>\n<li>4 / 2 = 2</li>\n<li>2 / 2 = 1</li>\n</ol>\n<p>Y a la hora de hablar de logaritmos, por defecto siempre hablamos de logaritmos base 2, por lo que lo podemos omitir (y así es como lo vemos en las gráficas).</p>\n<p>Bueno y hasta aquí lo básico, nos vemos en el siguiente, un abrazooorrrrr.</p>\n<!--kg-card-end: markdown-->","htmlAst":{"type":"root","children":[{"type":"comment","value":"kg-card-begin: markdown"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Hablemos de algoritmos, eficiencia y esas cosas, es decir, hablemos de cosas 'chungas'."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nPara medir la eficiencia de los algoritmos no usamos el tiempo propiamente dicho (como podríamos pensar en un primer momento), si lo midiéramos mediante algo temporal, como segundos, milisegundos o cosas así los datos no serían fiables, ya que dependen del hardware y de lo que esté haciendo en ese momento el ordenador."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nEn su lugar usamos 2 tipos de medidas:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Time complexity (complejidad temporal)"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Space complexity (complejidad espacial)"}]},{"type":"text","value":" o también lo podríamos llamar "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Auxiliary Space complexity"}]},{"type":"text","value":" (luego hablaremos de esto)."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y para cualquiera de estos tipos de medida usamos lo que se conoce como "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Big O notation"}]},{"type":"text","value":" o "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"notación de Landau"}]},{"type":"text","value":". No vamos a entrar en la matemática específica de esto, si queréis saber más tenéis más información "},{"type":"element","tagName":"a","properties":{"href":"https://es.wikipedia.org/wiki/Notaci%C3%B3n_de_Landau"},"children":[{"type":"text","value":"aquí"}]},{"type":"text","value":". En nuestro caso valdrá con que tengamos este diagrama como referencia"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2018/12/Capture.JPG","alt":"Capture"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Siendo "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"O(1)"}]},{"type":"text","value":" lo mejor y "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"O(n^2)"}]},{"type":"text","value":" lo peor. Con esto como base empecemos."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"timecomplexity"},"children":[{"type":"text","value":"TIME COMPLEXITY"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Al contrario de lo que indica su nombre no es una regla de medida temporal, lo que hace es medir la efeciencia basándose en el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"número de operaciones simples"}]},{"type":"text","value":" que realiza la función, entendiendo por operaciones simples: "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"=, +, -, *, /, %, <, >"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Veamoslo mejor con algunos ejemplos simples:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addUpTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"n"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" total "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" i"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" i "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<="}]},{"type":"text","value":" n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" i"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"++"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        total "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"+="}]},{"type":"text","value":" i"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" total"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Veamos cuantas operaciones tenemos aquí:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"let total=0"}]},{"type":"text","value":": Primera asignación que ocurre solo 1 vez."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"let i=0"}]},{"type":"text","value":": Segunda asignación que ocurre solo 1 vez."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n3 y 4. "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"i <= n"}]},{"type":"text","value":": Que se divide en 2 comparaciones 1 por el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"<"}]},{"type":"text","value":" y otra por el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"="}]},{"type":"text","value":" y esto se haría "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"n"}]},{"type":"text","value":" veces."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n5 y 6. "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"i++"}]},{"type":"text","value":": Esto es una suma y una asignación a i que se produce a su vez "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"n"}]},{"type":"text","value":" veces."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n7 y 8. "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"total += i"}]},{"type":"text","value":": Y esto es igual que el anterior una suma y una asignación que se produce "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"n"}]},{"type":"text","value":" veces."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En este caso tenemos "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"2 operaciones simples que se producen solo 1 vez"}]},{"type":"text","value":" y luego "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"6 operaciones que se producen n veces"}]},{"type":"text","value":", es decir, que dependen de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"n"}]},{"type":"text","value":", por lo tanto ¿cual creéis que será el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"TIME COMPLEXITY"}]},{"type":"text","value":" en este caso? Pensemos que son todo operaciones simples pero que dependen de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"n"}]},{"type":"text","value":", por lo que en este caso nuestro valor será "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"O(n)"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vayamos ahora con otro ejemplo:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addUpToV2"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"n"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" n "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"*"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"n "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"+"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"2"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Es la misma función, es decir, hace lo mismo, nos devuelve la suma de todos los valores menores que n incluido n. Veamos las operaciones:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"n+1"}]},{"type":"text","value":": Operación suma que se produce 1 vez."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"n * (resultado de lo anterior)"}]},{"type":"text","value":": Multiplicación del resultado anterior que se produce 1 vez."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"resultado anterior/2"}]},{"type":"text","value":": División del resultado anterior que se produce solo 1 vez."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En este caso tenemos solo 3 operaciones pero además estas operaciones "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"solo se producen una vez"}]},{"type":"text","value":", es decir, "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"no dependen de n"}]},{"type":"text","value":", por lo tanto, en este caso el valor sería O(1) puesto que pasemos el número que pasemos a n siempre es constante la cantidad de operaciones que se realizarán."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Otro ejemplo:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"countUpAndDown"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"n"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"Hacia arriba...\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n   \n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" i "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" i "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":" n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" i"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"++"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"i"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n    console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"En la cima \\n Bajando...\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" j "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" n "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"-"}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" j "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" j"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"--"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"j"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n    console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"Bajamos!!\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  \n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En este caso tenemos 2 bucles que como ya hemos visto cada una sería "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"O(n)"}]},{"type":"text","value":", es decir, "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"O(2n)"}]},{"type":"text","value":". Es "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"2n"}]},{"type":"text","value":" porque depende 2 veces de n, pero al medir la complejidad siempre "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"ignoramos los valores numéricos constantes"}]},{"type":"text","value":" por lo que volvemos a tener una función con un valor de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"0(n)"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y ahora vamos con el último ejemplo con las medidas simples de medida (de momento no entramos a las medidas logarítmicas)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"printAllPairs"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"n"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" i "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" i "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":" n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" i"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"++"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" j "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" j "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":" n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" j"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"++"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n            console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"i"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"j"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Aquí tenemos otro par de bucles, pero en este caso son 2 bucles anidados, es decir, uno dentro de otro, por lo que sería un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"n"}]},{"type":"text","value":" veces del bucle interior, por cada "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"n"}]},{"type":"text","value":" veces del bucle superior, es decir, "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"n*n"}]},{"type":"text","value":" o "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"n^2"}]},{"type":"text","value":", resumiendo en este caso tendríamos la peor medida de todas "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"O(n^2)"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Hasta aquí de momento en cuanto al "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Time Complexity"}]},{"type":"text","value":", más adelante volveremos a ello, ahora vamos a por el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Space Complexity"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"spacecomplexity"},"children":[{"type":"text","value":"SPACE COMPLEXITY"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Cuando hablamos de la "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"complejidad espacial"}]},{"type":"text","value":", nos referimos a cuanta memoria necesitaremos para ejecutar nuestra función. Al igual que con la "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"time complexity"}]},{"type":"text","value":", se usa para medir "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"O"}]},{"type":"text","value":", lo único que en este caso lo que diferenciamos será:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Valores primitivos"}]},{"type":"text","value":": number, boolean, undefined y null. Estos valores son siempre constantes en cuanto a su tamaño por lo que ocuparán "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"O(1)"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Objetos y arrays"}]},{"type":"text","value":": Que en este caso se miden en O(n) siendo "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"n la cantidad de keys en los objetos"}]},{"type":"text","value":" y "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"siendo n el tamaño de array"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En este caso la diferenciación es simple, si no tiene arrays u objetos será "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"O(1)"}]},{"type":"text","value":", si tiene n arrays u objetos "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"O(n)"}]},{"type":"text","value":" y si tiene arrays u objetos anidados entre sí sería "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"O(n^x)"}]},{"type":"text","value":" siendo "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" la cantidad de anidación que tengamos, es decir, si tenemos un array de 3 dimensiones tendremos un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"O(n^3)"}]},{"type":"text","value":", si tenemos uno de 2 "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"O(n^2)"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Esto en cuanto a la parte simple del "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"space complexity"}]},{"type":"text","value":" y del "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"time complexity"}]},{"type":"text","value":", evidentemente todo esto tiene algo más de chicha cuando entramos en los resultados intermedios de la gráfica (si, esos que contienen logaritmos). Hagamos un repaso de los logaritmos"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"logaritmos"},"children":[{"type":"text","value":"LOGARITMOS"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Hablemos ahora de los logaritmos, puesto que aunque no los hayamos visto todavía en algún ejemplo si que forman parte de las mediciones de eficiencia de los algoritmos. Si os fijáis en la gráfica inicial están presentes en las mediciones intermedias."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Pues veamos, ¿qué es un logaritmo? Para ponerlo simple es lo contrario que un exponente, es decir, ¿cuál es el resultado de 2^4? (2 elevado a 4)?"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"16"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nPor lo que entonces sería:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2018/12/Capture-7.JPG","alt":"Capture-7"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Una definición más específica sería:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nUn logaritmo es la cantidad de veces que tengo que dividir un número por 2 (si es de base 2) hasta tener un valor menor o igual a 1. En nuestro caso serían "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"4"}]},{"type":"text","value":" las veces que tenemos que dividir 16:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"16 / 2 = 8"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"8 / 2 = 4"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"4 / 2 = 2"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"2 / 2 = 1"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y a la hora de hablar de logaritmos, por defecto siempre hablamos de logaritmos base 2, por lo que lo podemos omitir (y así es como lo vemos en las gráficas)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bueno y hasta aquí lo básico, nos vemos en el siguiente, un abrazooorrrrr."}]},{"type":"text","value":"\n"},{"type":"comment","value":"kg-card-end: markdown"}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"timecomplexity","heading":"TIME COMPLEXITY"},{"id":"spacecomplexity","heading":"SPACE COMPLEXITY"},{"id":"logaritmos","heading":"LOGARITMOS"}]},"featureImageSharp":{"base":"unordered-3192273_640.png","publicURL":"/static/e92df4805fb46ec1f6bec181d2305365/unordered-3192273_640.png","imageMeta":{"width":640,"height":512},"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFG0lEQVQ4ywEQBe/6APG/tx3SpZ5Y2+PkQNzf3UjCw89E2M6jZubUibvJxK5Yk5/RHmd0qxNMWpUXsLO/LLe5xT+corsvv7++MmxsaxaZmYUXj4+WHsrKyjrNzc1HANSJfnXTZVT/1X5wp7K+vUSttMg40cSUb+zYh97by4ie0smidOHVpIbbzpWb7Nybsuvbmrbd0ZKAnp/khImK5tyWltuK4uHGPOXl6E3NyMdIAJFqZDnPkIiCwW5inMx1abl/j3YbtLb/AOjCOwXl1IRn2MmFntzNk5Tw46uQ493CYMS+olvt2X+avrSnpo6R6KCEhNulmZrkhs3SsikAABILAMfLzkae0MIY/6TMANl3X5vGi5ajeYjzhYiH66WJi+eaq7TzQuTZqG3v3I+008OFfpKk8ie0pm0n792VubCzwjPOzcE9hofluLOt43/Ue2F8ANfWxzZsXLEeh5X/UKZvjFq/eo3ml6HgedPLukaUk+KxjIvdlPnhcoXu2pwW6tWCl8/Iq1Lp15Cv5NacgElUgxje2r4yvcLqYZeH0tfZdGPhALu70USCg+mpgobwgoyG49zFeobjqqbhhYCO6YmDh+SynZ3VX+bUg4Dq1oeN7NiHxOjXj8jk0XNXfoaCFL29wE7Lx8dK0eznLZB8yaHSgH3MAJuc5qKGhuCF3tmJGo2S6rLIdnrJpYq+sLCIr8LKrbdquMG3RJuZo0vHu4eC6NeQy9HPwUuJjNporKzXYbuzoTe1uLtHuLe0P9BrY8C/fYF/AI+Q58Kur9NhvLfDQ3+K8pXFeW9m3nJZ2d1mRoLUb1ydv8HBKcPc+Cu1qoeG8+med5KY8HOYl+bKjo3nvwBn/w6J0MgV1nhjuayBsuFPctxCAIqK7qybm8txAAAAAXyG8Im3kraj2nBY0M9vZazlcWFlAAAADkseE59cLiD4TiMHc3570auip+BMkJnslKZ3q5PXYkie0GhZ4bR9ntm4na5oAIeJ4GGOj+7S1dDJTqe951G3e5nrx2pZTs2/pT+ZjH9IUSohtkYkGP9XJBf/WCIR/1gwNfV2ds+lv3SH1M97csHfiWiGynJ1za10ncfifGW3AOvajLKkn8qdgYLtx7LA8WbegnGkmn2+vJKn/39iRVHMXjcn/z87N/l/ZFP7OSol/0MsHrvEbG2usHef4ouY+aGJnvF1rn+ozdF3ccLMeGqWAOzZjN7444OryLyvuH2K+8C8iZ/U1IJ2oG+u/zB5ZHl8iHBd/6eWifvKqI3/npGF/ZR5bf/EbW3an7DGK6Sl5YuLiuf/jZb2obahhjO1vMJGAPLflS795oUW9+N/ld/QjMXYyJr43I1t9MdNJzUAOAADpodx58Gfh/+2pJbpw6GH+qSGc9rPblisqpfDcKWj1N7m2KHVo57Myri4vFCtpqwTAP///wA4Qu8NgYTuetbLs6rk1pb/ybOjt9VvZ6nCe3R8vZ6Dvph6YsCjhXPzi3FcsbWUgL/SalawjoTgrpufzW7YypGa3c+i5uvbk3jw34+GANDPuTesrNtxi4zo4oqN87bDubTD5NiUt9zOonzEh23DnoF+8JF8gsfRpHz/jndr07mIdvXMfGaGn6TvrJiW2L23sMDh18qbg8urAAXq2pGqANDQ0EM2NjUTeHidH5qZlSEABVkJ/+eDL9fJh43Hpn/zn4ym/6Ca0f+tnbD+nYaO/7eXhvmxroxy7N6gf8u/p57XzJ513+DcQ7e3uzE9PDMO7sYRFrnPY/gAAAAASUVORK5CYII=","aspectRatio":1.25,"src":"/static/e92df4805fb46ec1f6bec181d2305365/8bef3/unordered-3192273_640.png","srcSet":"/static/e92df4805fb46ec1f6bec181d2305365/bcfcb/unordered-3192273_640.png 260w,\n/static/e92df4805fb46ec1f6bec181d2305365/19d75/unordered-3192273_640.png 520w,\n/static/e92df4805fb46ec1f6bec181d2305365/8bef3/unordered-3192273_640.png 640w","srcWebp":"/static/e92df4805fb46ec1f6bec181d2305365/1ea2e/unordered-3192273_640.webp","srcSetWebp":"/static/e92df4805fb46ec1f6bec181d2305365/dc8f3/unordered-3192273_640.webp 260w,\n/static/e92df4805fb46ec1f6bec181d2305365/2db4b/unordered-3192273_640.webp 520w,\n/static/e92df4805fb46ec1f6bec181d2305365/1ea2e/unordered-3192273_640.webp 640w","sizes":"(max-width: 640px) 100vw, 640px"}}}},"prev":{"id":"Ghost__Post__5c1154572dd6610fd828cab0","title":"JS Algoritmos y estructuras de datos II: Resolución de problemas. Patrón Frequency Counter","slug":"js-algorithms-and-data-structures","featured":false,"feature_image":"https://jlgarcia.fulldev.ninja/assets/images/2019/01/unordered-3192273_640.png","excerpt":"Antes de empezar a ver algoritmos complejos o las estructuras de datos entremos\nun poco en el área de la resolución de problemas que, aunque no te lo creas,\nexisten algunos patrones típicos que podemos usar para resolver problemas y que\npueden ser bastante útiles en nuestro dia a dia o por lo menos a la hora de\nhacer entrevistas. Aquí veremos algunos de estos patrones para que nos hagamos\nuna idea y luego simplemente sería ir buscando más. Empecemos.\n\nResolución de problemas\nAntes de entrar a ve","custom_excerpt":null,"visibility":"public","created_at_pretty":"12 Dec 2018","published_at_pretty":"15 Jan 2019","updated_at_pretty":"19 Jan 2021","created_at":"2018-12-12T19:32:55.000+01:00","published_at":"2019-01-15T18:48:01.000+01:00","updated_at":"2021-01-19T20:58:00.000+01:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"Perfil.jpg","publicURL":"/static/b0de6281fb28a266510b3b09b9243e5a/Perfil.jpg","imageMeta":{"width":307,"height":307},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUDBAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGzw6zC6zHn+cLYP//EAB0QAAICAQUAAAAAAAAAAAAAAAEDAAIEEyEiIzL/2gAIAQEAAQUCifca8KgcKWVfUpkHsG5pxX//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAdEAACAgEFAAAAAAAAAAAAAAAAARARcQISIUFR/9oACAEBAAY/AhU88xkb7N06a8P/xAAcEAEAAwEAAwEAAAAAAAAAAAABABEhMUFRYXH/2gAIAQEAAT8hR2pq40aqb+xIAeXibhW9JXr8joF4TBcSNe0//9oADAMBAAIAAwAAABDzDwD/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAcEAEAAgIDAQAAAAAAAAAAAAABABEhUTFhcfD/2gAIAQEAAT8QyItrELaTlatLwU63MvEW6vUNdy4LZQDn7iVApV9VLtANdWwKkuYq4Er1VZ//2Q==","aspectRatio":1,"src":"/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg","srcSet":"/static/b0de6281fb28a266510b3b09b9243e5a/f340b/Perfil.jpg 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/22d64/Perfil.jpg 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/aa249/Perfil.jpg 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/0dc33/Perfil.jpg 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/60667/Perfil.jpg 307w","srcWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp","srcSetWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/59cda/Perfil.webp 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/7da75/Perfil.webp 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f282e/Perfil.webp 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/a7b21/Perfil.webp 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f59af/Perfil.webp 307w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"algoritmos","url":"https://jlgarcia.fulldev.ninja/tag/algoritmos/","name":"algoritmos","visibility":"public","feature_image":null,"description":null,"meta_title":null,"meta_description":null,"featureImageSharp":null},"tags":[{"slug":"algoritmos","url":"https://jlgarcia.fulldev.ninja/tag/algoritmos/","name":"algoritmos","visibility":"public","feature_image":null,"description":null,"meta_title":null,"meta_description":null,"featureImageSharp":null}],"plaintext":"Antes de empezar a ver algoritmos complejos o las estructuras de datos entremos\nun poco en el área de la resolución de problemas que, aunque no te lo creas,\nexisten algunos patrones típicos que podemos usar para resolver problemas y que\npueden ser bastante útiles en nuestro dia a dia o por lo menos a la hora de\nhacer entrevistas. Aquí veremos algunos de estos patrones para que nos hagamos\nuna idea y luego simplemente sería ir buscando más. Empecemos.\n\nResolución de problemas\nAntes de entrar a ver patrones, vamos a comentar un poco algunos conceptos\nimportantes.\nEmpecemos por preguntarnos, ¿qué es un algoritmo?... Por ponerlo simple podemos\ndefinirlo como un proceso o serie de pasos que tenemos que seguir para completar\nuna tarea específica o para resolver un problema (algo así podría valer ¿no?).\nY esto ¿por qué es importante?... si lo pensamos detenidamente los\ndesarrolladores realmente lo que hacemos es resolver problemas (muchos de estos\nlos generamos nosotros mismos pero eso es otro tema) y aunque en nuestro día a\ndía realmente puede que no necesitemos usar procesos complejos para nuestro\ntrabajo, siempre estamos haciendo uso de algoritmos y como casi siempre en\nprogramación, alguien ya se ha encontrado con el problema que tenemos\nactualmente y puede ser que exista una manera mejor o más eficiente para\nresolver un problema en el que, por ejemplo, estemos usando bucles anidados o\ncosas similares (ya hemos visto que eso es kaka). Básicamente podemos entender\nque los algoritmos son como nuestras bases para ser mejores programadores y\nresolutores de problemas. También que aunque en vuestro dia a dia al final no\nhagáis uso de esto, siempre os podrá venir bien para las entrevistas o para las \npruebas técnicas, que ahora cada vez más están recurriendo a este tipo de\npruebas y muchas contienen problemas que podéis resolver con este tipo de\npatrones.\n\nBest Practices\nComo en la mayoría de entornos a la hora de resolver problemas tenemos unas best\npractices reconocidas (que realmente no usamos) y que podemos usarlas en última\ninstancia si no somos capaces de resolver el problema que tenemos entre manos.\nEsto sería lo que llamaríamos Idear un plan de resolución de problemas, luego\ntenemos la otra opción que es dominar los patrones de resolución de problemas y\naplicarlos directamente (ya llegaremos a esto demomoento empecemos con nuestro\nplan).\n\nPasos básicos para resolver un problema\nEstos serían los pasos básicos que podemos seguir para resolver un problema:\n1. Entender realmente el problema\n2. Revisar ejemplos concretos de este problema\n3. Descomponer el problema en problemas más pequeños y asumibles\n4. Resolver o simplificar\n5. Revisar y refactorizar\n\n1. Entender el problema\nPara ver si realmente entendemos el problema podemos hacernos algunas preguntas\nbásicas:\n* ¿Puedo replantear el problema con mis propias palabras?\n* ¿Cuáles son realmente los inputs?\n* ¿Cuáles son los outputs que debería devolver la solución del problema?\n* ¿La salida puede ser determinada con los elementos que recibe el\nproblema?¿Tenemos toda la información que necesitamos para resolver el problema?\n* ¿Como debo identificar los datos importantes que son parte del problema?\n\nLo primero seria resolver preguntas de este tipo para poder hacernos una idea de\nlo que necesitamos y donde tenemos las mayores dificultades con este problema.\n\n2. Buscar ejemplos\nSi no tenemos ejemplos con la entrada y los resultados que deberíamos obtener,\npodemos tener tests o historias de usuario, pero al final, necesitamos algún\ntipo de pista de que es lo que necesitamos conseguir.\nA continuación podemos plantearnos empezar creando nosotros mismos ejemplos\nsimples (podemos incluso simplificar un poco el problema ignorando algunas de\nsus condiciones) e ir avanzando añadiendo dificultad hasta tener toda la\ncomplejidad que el problema realmente tiene. OJO no se nos pueden olvidar\nejemplos con entras vacías o erroneas.\n\n3. Descomponer el problema\nEn este punto debemos escribir los pasos que necesitamos tomar para resolver el\nproblema, y sí escribir aunque parezca una tontería esto nos ayuda a plantear la\nresolución del problema correctamente viendo posibles fallos en nuestro\nplanteamiento antes de escribir una sola línea de código. Al escribir los pasos,\nlos estamos descomponiendo en otros más pequeños que son más sencillos de\nenfrentar.\n\n4. Resolver el problema/Simplificando el problema\nAhora llega el punto de realmente resolver el problema. A la hora de intentar\nresolverlo nos daremos cuenta donde realmente estará el núcleo de la difilcutad\nque tenemos para llegar a revolver el problema. En este punto lo que debemos\nhacer es ignorar esa dificultad, es decir, simplificamos el problema y lo\nresolvemos de esta manera. Una vez que esté resuelto volvemos a incorporar esa\ndificultad a nuestra solución.\nAunque no lo parezca, este proceso ayuda muchas veces a resolver nuestro\nproblema.\n\n5. Revisar y refactorizar\nEn este punto lo que tendríamos que hacer sería comprobar, lo primero, si\nnuestra solución realmente funciona en todos los casos y luego ya hacernos\npreguntas de este estilo:\n- ¿Podemos llegar a la misma solución de otra manera?\n- ¿Podemos usar este algoritmo para resolver otros problemas?\n- ¿Podemos mejorar el rendimiento de nuestra solución?\n- ¿Cómo han resuelto el problema otros desarrolladores?\n\nCon un plan o estrategia similar a estos 5 puntos podemos acercarnos más a una\nsolución a nuestro problema.\n\nY a continuación esta estrategia la complementaremos con nuestro conocimiento en\nalgunos patrones típicos de resolución de problemas.\n\nCommon problem solving patterns\nExisten multitud de patrones de resolución de problemas:\n- Frequency Counter\n- Multiple Pointers\n- Sliding Window\n- Divide and Conquer\n- Dynamic Programming\n- Greedy Algorithms\n- ....\n\nAquí comentaremos algunos que están en el nivel correcto sencillez/utilidad pero\nen esta página GeeksForGeeks\n[https://www.geeksforgeeks.org/fundamentals-of-algorithms/] tenemos todos los\npatrones o algoritmos que podamos necesitar (es muy completa).\n\nVamos a empezar viendo el que se conoce como Frequency Counter\n\nPatrón FREQUENCY COUNTER\nEste patrón es relativamente sencillo y tiene una función muy específica \"Contar\nlas veces que algo se repite o aparece\". En un primer momento podemos pensar en\nla utilidad de esto, veamoslo con un ejemplo.\n\nQueremos un método que compruebe si un string es un anagrama de otro, es decir,\nqueremos saber si ambos strings se pueden formar con las mismas letras. Una\nforma fácil es contar las veces que existe cada letra en ambos strings y\ncomparar, veremos dos acercamientos posibles de este patrón\n\nfunction validAnagram(string1, string2){\n    \n    //Comprobamos si el tamaño es el mismo,si no, terminamos antes de empezar\n    if (string1.length !== string2.length){\n        return false;\n    }\n    \n    const frequency1 = {};\n    const frequency2 = {};\n    //Recorremos ambos strings y guardamos en un objeto siendo la letra la key y el valor el número de veces que aparece\n    for (let char of string1){\n        frequency1[char] = ++frequency1[char] || 1;\n    }\n    \n    for (let char of string2){\n        frequency2[char] = ++frequency2[char] || 1;\n    }\n\n    //Recorremos y comprobamos. Si en algún caso las cantidades no coinciden entonces no es un anagrama uno de otro\n    for (let char in frequency1){\n        \n        if(frequency1[char] !== frequency2[char]){\n            return false;\n        }\n    }\n    return true;\n  }\n\n\nEsta es una solución válida, que excepto que tenemos 3 búcles for, no está mal.\nVeamos otro posible acercamiento en este caso son solo 2 búcles\n\nfunction validAnagram(string1, string2){\n    //Comprobamos si el tamaño es el mismo,si no, terminamos antes de empezar\n    if (string1.length !== string2.length){\n        return false;\n    }\n    const letters = {};\n    \n    for (let i = 0; i < string1.length; i++){\n        letters[string1[i]] = ++letters[string1[i]] || 1;\n    }\n    \n    for (let i = 0; i < string2.length; i++){\n    //Si es 0 o no existe no es un anagrama.\n        if(!letters[string2[i]]){\n            return false;\n        } else {\n            letters[string2[i]] -= 1;\n        }\n    }\n    return true;\n}\n\n\nEn este caso tenemos otra solución que tiene un búcle for menos y también nos\nfunciona. Por si a alguien no le queda claro lo que estamos haciendo es restando\nlas coincidencias del segundo string con el primero dentro de nuestro objeto\nletters y en el caso de que intentemos acceder a un valor que ya es 0 o que no\nexista es señal de que no es un anagrama.\n\nBueno y hasta aquí el patrón de Frequency Count, básicamente contamos dentro de\nun objeto CLAVE-VALOR los elementos que nos interesen, sencillo ¿verdad?\n\nNos vemos en el siguiente, un abrazooooooorrrrrrrr.","html":"<!--kg-card-begin: markdown--><p>Antes de empezar a ver algoritmos complejos o las estructuras de datos entremos un poco en el área de la <strong>resolución de problemas</strong> que, aunque no te lo creas, existen algunos patrones típicos que podemos usar para resolver problemas y que pueden ser bastante útiles en nuestro dia a dia o por lo menos a la hora de hacer entrevistas. Aquí veremos algunos de estos patrones para que nos hagamos una idea y luego simplemente sería ir buscando más. Empecemos.</p>\n<h2 id=\"resolucindeproblemas\">Resolución de problemas</h2>\n<p>Antes de entrar a ver patrones, vamos a comentar un poco algunos conceptos importantes.<br>\nEmpecemos por preguntarnos, ¿qué es un algoritmo?... Por ponerlo simple podemos definirlo <em>como un proceso o serie de pasos que tenemos que seguir para completar una tarea específica o para resolver un problema</em> (algo así podría valer ¿no?).<br>\nY esto ¿por qué es importante?... si lo pensamos detenidamente los desarrolladores realmente lo que hacemos es resolver problemas (muchos de estos los generamos nosotros mismos pero eso es otro tema) y aunque en nuestro día a día realmente puede que no necesitemos usar procesos complejos para nuestro trabajo, siempre estamos haciendo uso de algoritmos y como casi siempre en programación, alguien ya se ha encontrado con el problema que tenemos actualmente y puede ser que exista una manera mejor o más eficiente para resolver un problema en el que, por ejemplo, estemos usando bucles anidados o cosas similares (ya hemos visto que eso es kaka). Básicamente podemos entender que los algoritmos son como nuestras bases para ser mejores programadores y resolutores de problemas. También que aunque en vuestro dia a dia al final no hagáis uso de esto, siempre os podrá venir bien para las <strong>entrevistas</strong> o para las <strong>pruebas técnicas</strong>, que ahora cada vez más están recurriendo a este tipo de pruebas y muchas contienen problemas que podéis resolver con este tipo de patrones.</p>\n<h3 id=\"bestpractices\">Best Practices</h3>\n<p>Como en la mayoría de entornos a la hora de resolver problemas tenemos unas <strong>best practices</strong> reconocidas (que realmente no usamos) y que podemos usarlas en última instancia si no somos capaces de resolver el problema que tenemos entre manos. Esto sería lo que llamaríamos <strong>Idear un plan de resolución de problemas</strong>, luego tenemos la otra opción que es <strong>dominar los patrones de resolución de problemas</strong> y aplicarlos directamente (ya llegaremos a esto demomoento empecemos con nuestro plan).</p>\n<h4 id=\"pasosbsicospararesolverunproblema\">Pasos básicos para resolver un problema</h4>\n<p>Estos serían los pasos básicos que podemos seguir para resolver un problema:<br>\n1. Entender realmente el problema<br>\n2. Revisar ejemplos concretos de este problema<br>\n3. Descomponer el problema en problemas más pequeños y asumibles<br>\n4. Resolver o simplificar<br>\n5. Revisar y refactorizar</p>\n<p><strong>1. Entender el problema</strong><br>\nPara ver si realmente entendemos el problema podemos hacernos algunas preguntas básicas:<br>\n* ¿Puedo replantear el problema con mis propias palabras?<br>\n* ¿Cuáles son realmente los inputs?<br>\n* ¿Cuáles son los outputs que debería devolver la solución del problema?<br>\n* ¿La salida puede ser determinada con los elementos que recibe el problema?¿Tenemos toda la información que necesitamos para resolver el problema?<br>\n* ¿Como debo identificar los datos importantes que son parte del problema?</p>\n<p>Lo primero seria resolver preguntas de este tipo para poder hacernos una idea de lo que necesitamos y donde tenemos las mayores dificultades con este problema.</p>\n<p><strong>2. Buscar ejemplos</strong><br>\nSi no tenemos ejemplos con la entrada y los resultados que deberíamos obtener, podemos tener tests o historias de usuario, pero al final, necesitamos algún tipo de pista de que es lo que necesitamos conseguir.<br>\nA continuación podemos plantearnos empezar creando nosotros mismos ejemplos simples (podemos incluso simplificar un poco el problema ignorando algunas de sus condiciones) e ir avanzando añadiendo dificultad hasta tener toda la complejidad que el problema realmente tiene. OJO no se nos pueden olvidar ejemplos con entras vacías o erroneas.</p>\n<p><strong>3. Descomponer el problema</strong><br>\nEn este punto debemos escribir los pasos que necesitamos tomar para resolver el problema, y sí <strong>escribir</strong> aunque parezca una tontería esto nos ayuda a plantear la resolución del problema correctamente viendo posibles fallos en nuestro planteamiento antes de escribir una sola línea de código. Al escribir los pasos, los estamos descomponiendo en otros más pequeños que son más sencillos de enfrentar.</p>\n<p><strong>4. Resolver el problema/Simplificando el problema</strong><br>\nAhora llega el punto de realmente resolver el problema. A la hora de intentar resolverlo nos daremos cuenta donde realmente estará el núcleo de la difilcutad que tenemos para llegar a revolver el problema. En este punto lo que debemos hacer es ignorar esa dificultad, es decir, simplificamos el problema y lo resolvemos de esta manera. Una vez que esté resuelto volvemos a incorporar esa dificultad a nuestra solución.<br>\nAunque no lo parezca, este proceso ayuda muchas veces a resolver nuestro problema.</p>\n<p><strong>5. Revisar y refactorizar</strong><br>\nEn este punto lo que tendríamos que hacer sería comprobar, lo primero, si nuestra solución realmente funciona en todos los casos y luego ya hacernos preguntas de este estilo:<br>\n- ¿Podemos llegar a la misma solución de otra manera?<br>\n- ¿Podemos usar este algoritmo para resolver otros problemas?<br>\n- ¿Podemos mejorar el rendimiento de nuestra solución?<br>\n- ¿Cómo han resuelto el problema otros desarrolladores?</p>\n<p>Con un plan o estrategia similar a estos 5 puntos podemos acercarnos más a una solución a nuestro problema.</p>\n<p>Y a continuación esta estrategia la complementaremos con nuestro conocimiento en algunos patrones típicos de resolución de problemas.</p>\n<h3 id=\"commonproblemsolvingpatterns\">Common problem solving patterns</h3>\n<p>Existen multitud de patrones de resolución de problemas:<br>\n- Frequency Counter<br>\n- Multiple Pointers<br>\n- Sliding Window<br>\n- Divide and Conquer<br>\n- Dynamic Programming<br>\n- Greedy Algorithms<br>\n- ....</p>\n<p>Aquí comentaremos algunos que están en el nivel correcto sencillez/utilidad pero en esta página <a href=\"https://www.geeksforgeeks.org/fundamentals-of-algorithms/\">GeeksForGeeks</a> tenemos todos los patrones o algoritmos que podamos necesitar (es muy completa).</p>\n<p>Vamos a empezar viendo el que se conoce como <em>Frequency Counter</em></p>\n<h3 id=\"patrnfrequencycounter\">Patrón FREQUENCY COUNTER</h3>\n<p>Este patrón es relativamente sencillo y tiene una función muy específica <em>&quot;Contar las veces que algo se repite o aparece&quot;</em>. En un primer momento podemos pensar en la utilidad de esto, veamoslo con un ejemplo.</p>\n<p>Queremos un método que compruebe si un string es un <em>anagrama</em> de otro, es decir, queremos saber si ambos strings se pueden formar con las mismas letras. Una forma fácil es contar las veces que existe cada letra en ambos strings y comparar, veremos dos acercamientos posibles de este patrón</p>\n<pre><code class=\"language-javascript\">function validAnagram(string1, string2){\n    \n    //Comprobamos si el tamaño es el mismo,si no, terminamos antes de empezar\n    if (string1.length !== string2.length){\n        return false;\n    }\n    \n    const frequency1 = {};\n    const frequency2 = {};\n    //Recorremos ambos strings y guardamos en un objeto siendo la letra la key y el valor el número de veces que aparece\n    for (let char of string1){\n        frequency1[char] = ++frequency1[char] || 1;\n    }\n    \n    for (let char of string2){\n        frequency2[char] = ++frequency2[char] || 1;\n    }\n\n    //Recorremos y comprobamos. Si en algún caso las cantidades no coinciden entonces no es un anagrama uno de otro\n    for (let char in frequency1){\n        \n        if(frequency1[char] !== frequency2[char]){\n            return false;\n        }\n    }\n    return true;\n  }\n</code></pre>\n<p>Esta es una solución válida, que excepto que tenemos 3 búcles for, no está mal. Veamos otro posible acercamiento en este caso son solo 2 búcles</p>\n<pre><code class=\"language-javascript\">function validAnagram(string1, string2){\n    //Comprobamos si el tamaño es el mismo,si no, terminamos antes de empezar\n    if (string1.length !== string2.length){\n        return false;\n    }\n    const letters = {};\n    \n    for (let i = 0; i &lt; string1.length; i++){\n        letters[string1[i]] = ++letters[string1[i]] || 1;\n    }\n    \n    for (let i = 0; i &lt; string2.length; i++){\n    //Si es 0 o no existe no es un anagrama.\n        if(!letters[string2[i]]){\n            return false;\n        } else {\n            letters[string2[i]] -= 1;\n        }\n    }\n    return true;\n}\n</code></pre>\n<p>En este caso tenemos otra solución que tiene un búcle for menos y también nos funciona. Por si a alguien no le queda claro lo que estamos haciendo es restando las coincidencias del segundo string con el primero dentro de nuestro objeto letters y en el caso de que intentemos acceder a un valor que ya es 0 o que no exista es señal de que no es un anagrama.</p>\n<p>Bueno y hasta aquí el patrón de <strong>Frequency Count</strong>, básicamente contamos dentro de un objeto CLAVE-VALOR los elementos que nos interesen, sencillo ¿verdad?</p>\n<p>Nos vemos en el siguiente, un abrazooooooorrrrrrrr.</p>\n<!--kg-card-end: markdown-->","url":"https://jlgarcia.fulldev.ninja/js-algorithms-and-data-structures/","canonical_url":null,"uuid":"07e008cb-8d58-48f5-adfb-0d1ae3a6a86a","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"5c1154572dd6610fd828cab0","reading_time":5,"send_email_when_published":false,"email_subject":null,"childHtmlRehype":{"html":"<!--kg-card-begin: markdown--><p>Antes de empezar a ver algoritmos complejos o las estructuras de datos entremos un poco en el área de la <strong>resolución de problemas</strong> que, aunque no te lo creas, existen algunos patrones típicos que podemos usar para resolver problemas y que pueden ser bastante útiles en nuestro dia a dia o por lo menos a la hora de hacer entrevistas. Aquí veremos algunos de estos patrones para que nos hagamos una idea y luego simplemente sería ir buscando más. Empecemos.</p>\n<h2 id=\"resolucindeproblemas\">Resolución de problemas</h2>\n<p>Antes de entrar a ver patrones, vamos a comentar un poco algunos conceptos importantes.<br>\nEmpecemos por preguntarnos, ¿qué es un algoritmo?... Por ponerlo simple podemos definirlo <em>como un proceso o serie de pasos que tenemos que seguir para completar una tarea específica o para resolver un problema</em> (algo así podría valer ¿no?).<br>\nY esto ¿por qué es importante?... si lo pensamos detenidamente los desarrolladores realmente lo que hacemos es resolver problemas (muchos de estos los generamos nosotros mismos pero eso es otro tema) y aunque en nuestro día a día realmente puede que no necesitemos usar procesos complejos para nuestro trabajo, siempre estamos haciendo uso de algoritmos y como casi siempre en programación, alguien ya se ha encontrado con el problema que tenemos actualmente y puede ser que exista una manera mejor o más eficiente para resolver un problema en el que, por ejemplo, estemos usando bucles anidados o cosas similares (ya hemos visto que eso es kaka). Básicamente podemos entender que los algoritmos son como nuestras bases para ser mejores programadores y resolutores de problemas. También que aunque en vuestro dia a dia al final no hagáis uso de esto, siempre os podrá venir bien para las <strong>entrevistas</strong> o para las <strong>pruebas técnicas</strong>, que ahora cada vez más están recurriendo a este tipo de pruebas y muchas contienen problemas que podéis resolver con este tipo de patrones.</p>\n<h3 id=\"bestpractices\">Best Practices</h3>\n<p>Como en la mayoría de entornos a la hora de resolver problemas tenemos unas <strong>best practices</strong> reconocidas (que realmente no usamos) y que podemos usarlas en última instancia si no somos capaces de resolver el problema que tenemos entre manos. Esto sería lo que llamaríamos <strong>Idear un plan de resolución de problemas</strong>, luego tenemos la otra opción que es <strong>dominar los patrones de resolución de problemas</strong> y aplicarlos directamente (ya llegaremos a esto demomoento empecemos con nuestro plan).</p>\n<h4 id=\"pasosbsicospararesolverunproblema\">Pasos básicos para resolver un problema</h4>\n<p>Estos serían los pasos básicos que podemos seguir para resolver un problema:<br>\n1. Entender realmente el problema<br>\n2. Revisar ejemplos concretos de este problema<br>\n3. Descomponer el problema en problemas más pequeños y asumibles<br>\n4. Resolver o simplificar<br>\n5. Revisar y refactorizar</p>\n<p><strong>1. Entender el problema</strong><br>\nPara ver si realmente entendemos el problema podemos hacernos algunas preguntas básicas:<br>\n* ¿Puedo replantear el problema con mis propias palabras?<br>\n* ¿Cuáles son realmente los inputs?<br>\n* ¿Cuáles son los outputs que debería devolver la solución del problema?<br>\n* ¿La salida puede ser determinada con los elementos que recibe el problema?¿Tenemos toda la información que necesitamos para resolver el problema?<br>\n* ¿Como debo identificar los datos importantes que son parte del problema?</p>\n<p>Lo primero seria resolver preguntas de este tipo para poder hacernos una idea de lo que necesitamos y donde tenemos las mayores dificultades con este problema.</p>\n<p><strong>2. Buscar ejemplos</strong><br>\nSi no tenemos ejemplos con la entrada y los resultados que deberíamos obtener, podemos tener tests o historias de usuario, pero al final, necesitamos algún tipo de pista de que es lo que necesitamos conseguir.<br>\nA continuación podemos plantearnos empezar creando nosotros mismos ejemplos simples (podemos incluso simplificar un poco el problema ignorando algunas de sus condiciones) e ir avanzando añadiendo dificultad hasta tener toda la complejidad que el problema realmente tiene. OJO no se nos pueden olvidar ejemplos con entras vacías o erroneas.</p>\n<p><strong>3. Descomponer el problema</strong><br>\nEn este punto debemos escribir los pasos que necesitamos tomar para resolver el problema, y sí <strong>escribir</strong> aunque parezca una tontería esto nos ayuda a plantear la resolución del problema correctamente viendo posibles fallos en nuestro planteamiento antes de escribir una sola línea de código. Al escribir los pasos, los estamos descomponiendo en otros más pequeños que son más sencillos de enfrentar.</p>\n<p><strong>4. Resolver el problema/Simplificando el problema</strong><br>\nAhora llega el punto de realmente resolver el problema. A la hora de intentar resolverlo nos daremos cuenta donde realmente estará el núcleo de la difilcutad que tenemos para llegar a revolver el problema. En este punto lo que debemos hacer es ignorar esa dificultad, es decir, simplificamos el problema y lo resolvemos de esta manera. Una vez que esté resuelto volvemos a incorporar esa dificultad a nuestra solución.<br>\nAunque no lo parezca, este proceso ayuda muchas veces a resolver nuestro problema.</p>\n<p><strong>5. Revisar y refactorizar</strong><br>\nEn este punto lo que tendríamos que hacer sería comprobar, lo primero, si nuestra solución realmente funciona en todos los casos y luego ya hacernos preguntas de este estilo:<br>\n- ¿Podemos llegar a la misma solución de otra manera?<br>\n- ¿Podemos usar este algoritmo para resolver otros problemas?<br>\n- ¿Podemos mejorar el rendimiento de nuestra solución?<br>\n- ¿Cómo han resuelto el problema otros desarrolladores?</p>\n<p>Con un plan o estrategia similar a estos 5 puntos podemos acercarnos más a una solución a nuestro problema.</p>\n<p>Y a continuación esta estrategia la complementaremos con nuestro conocimiento en algunos patrones típicos de resolución de problemas.</p>\n<h3 id=\"commonproblemsolvingpatterns\">Common problem solving patterns</h3>\n<p>Existen multitud de patrones de resolución de problemas:<br>\n- Frequency Counter<br>\n- Multiple Pointers<br>\n- Sliding Window<br>\n- Divide and Conquer<br>\n- Dynamic Programming<br>\n- Greedy Algorithms<br>\n- ....</p>\n<p>Aquí comentaremos algunos que están en el nivel correcto sencillez/utilidad pero en esta página <a href=\"https://www.geeksforgeeks.org/fundamentals-of-algorithms/\">GeeksForGeeks</a> tenemos todos los patrones o algoritmos que podamos necesitar (es muy completa).</p>\n<p>Vamos a empezar viendo el que se conoce como <em>Frequency Counter</em></p>\n<h3 id=\"patrnfrequencycounter\">Patrón FREQUENCY COUNTER</h3>\n<p>Este patrón es relativamente sencillo y tiene una función muy específica <em>\"Contar las veces que algo se repite o aparece\"</em>. En un primer momento podemos pensar en la utilidad de esto, veamoslo con un ejemplo.</p>\n<p>Queremos un método que compruebe si un string es un <em>anagrama</em> de otro, es decir, queremos saber si ambos strings se pueden formar con las mismas letras. Una forma fácil es contar las veces que existe cada letra en ambos strings y comparar, veremos dos acercamientos posibles de este patrón</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token function\">validAnagram</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">string1<span class=\"token punctuation\">,</span> string2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n    \n    <span class=\"token comment\">//Comprobamos si el tamaño es el mismo,si no, terminamos antes de empezar</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>string1<span class=\"token punctuation\">.</span>length <span class=\"token operator\">!==</span> string2<span class=\"token punctuation\">.</span>length<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    \n    <span class=\"token keyword\">const</span> frequency1 <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">const</span> frequency2 <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">//Recorremos ambos strings y guardamos en un objeto siendo la letra la key y el valor el número de veces que aparece</span>\n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">let</span> char <span class=\"token keyword\">of</span> string1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        frequency1<span class=\"token punctuation\">[</span>char<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token operator\">++</span>frequency1<span class=\"token punctuation\">[</span>char<span class=\"token punctuation\">]</span> <span class=\"token operator\">||</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    \n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">let</span> char <span class=\"token keyword\">of</span> string2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        frequency2<span class=\"token punctuation\">[</span>char<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token operator\">++</span>frequency2<span class=\"token punctuation\">[</span>char<span class=\"token punctuation\">]</span> <span class=\"token operator\">||</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token comment\">//Recorremos y comprobamos. Si en algún caso las cantidades no coinciden entonces no es un anagrama uno de otro</span>\n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">let</span> char <span class=\"token keyword\">in</span> frequency1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        \n        <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>frequency1<span class=\"token punctuation\">[</span>char<span class=\"token punctuation\">]</span> <span class=\"token operator\">!==</span> frequency2<span class=\"token punctuation\">[</span>char<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">return</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n</code></pre></div>\n<p>Esta es una solución válida, que excepto que tenemos 3 búcles for, no está mal. Veamos otro posible acercamiento en este caso son solo 2 búcles</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token function\">validAnagram</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">string1<span class=\"token punctuation\">,</span> string2</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">//Comprobamos si el tamaño es el mismo,si no, terminamos antes de empezar</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>string1<span class=\"token punctuation\">.</span>length <span class=\"token operator\">!==</span> string2<span class=\"token punctuation\">.</span>length<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">const</span> letters <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n    \n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">let</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&#x3C;</span> string1<span class=\"token punctuation\">.</span>length<span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n        letters<span class=\"token punctuation\">[</span>string1<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token operator\">++</span>letters<span class=\"token punctuation\">[</span>string1<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">||</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    \n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">let</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&#x3C;</span> string2<span class=\"token punctuation\">.</span>length<span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">//Si es 0 o no existe no es un anagrama.</span>\n        <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>letters<span class=\"token punctuation\">[</span>string2<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">return</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n            letters<span class=\"token punctuation\">[</span>string2<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">-=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n</code></pre></div>\n<p>En este caso tenemos otra solución que tiene un búcle for menos y también nos funciona. Por si a alguien no le queda claro lo que estamos haciendo es restando las coincidencias del segundo string con el primero dentro de nuestro objeto letters y en el caso de que intentemos acceder a un valor que ya es 0 o que no exista es señal de que no es un anagrama.</p>\n<p>Bueno y hasta aquí el patrón de <strong>Frequency Count</strong>, básicamente contamos dentro de un objeto CLAVE-VALOR los elementos que nos interesen, sencillo ¿verdad?</p>\n<p>Nos vemos en el siguiente, un abrazooooooorrrrrrrr.</p>\n<!--kg-card-end: markdown-->","htmlAst":{"type":"root","children":[{"type":"comment","value":"kg-card-begin: markdown"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Antes de empezar a ver algoritmos complejos o las estructuras de datos entremos un poco en el área de la "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"resolución de problemas"}]},{"type":"text","value":" que, aunque no te lo creas, existen algunos patrones típicos que podemos usar para resolver problemas y que pueden ser bastante útiles en nuestro dia a dia o por lo menos a la hora de hacer entrevistas. Aquí veremos algunos de estos patrones para que nos hagamos una idea y luego simplemente sería ir buscando más. Empecemos."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"resolucindeproblemas"},"children":[{"type":"text","value":"Resolución de problemas"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Antes de entrar a ver patrones, vamos a comentar un poco algunos conceptos importantes."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nEmpecemos por preguntarnos, ¿qué es un algoritmo?... Por ponerlo simple podemos definirlo "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"como un proceso o serie de pasos que tenemos que seguir para completar una tarea específica o para resolver un problema"}]},{"type":"text","value":" (algo así podría valer ¿no?)."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nY esto ¿por qué es importante?... si lo pensamos detenidamente los desarrolladores realmente lo que hacemos es resolver problemas (muchos de estos los generamos nosotros mismos pero eso es otro tema) y aunque en nuestro día a día realmente puede que no necesitemos usar procesos complejos para nuestro trabajo, siempre estamos haciendo uso de algoritmos y como casi siempre en programación, alguien ya se ha encontrado con el problema que tenemos actualmente y puede ser que exista una manera mejor o más eficiente para resolver un problema en el que, por ejemplo, estemos usando bucles anidados o cosas similares (ya hemos visto que eso es kaka). Básicamente podemos entender que los algoritmos son como nuestras bases para ser mejores programadores y resolutores de problemas. También que aunque en vuestro dia a dia al final no hagáis uso de esto, siempre os podrá venir bien para las "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"entrevistas"}]},{"type":"text","value":" o para las "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"pruebas técnicas"}]},{"type":"text","value":", que ahora cada vez más están recurriendo a este tipo de pruebas y muchas contienen problemas que podéis resolver con este tipo de patrones."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"bestpractices"},"children":[{"type":"text","value":"Best Practices"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como en la mayoría de entornos a la hora de resolver problemas tenemos unas "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"best practices"}]},{"type":"text","value":" reconocidas (que realmente no usamos) y que podemos usarlas en última instancia si no somos capaces de resolver el problema que tenemos entre manos. Esto sería lo que llamaríamos "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Idear un plan de resolución de problemas"}]},{"type":"text","value":", luego tenemos la otra opción que es "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"dominar los patrones de resolución de problemas"}]},{"type":"text","value":" y aplicarlos directamente (ya llegaremos a esto demomoento empecemos con nuestro plan)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h4","properties":{"id":"pasosbsicospararesolverunproblema"},"children":[{"type":"text","value":"Pasos básicos para resolver un problema"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Estos serían los pasos básicos que podemos seguir para resolver un problema:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n1. Entender realmente el problema"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n2. Revisar ejemplos concretos de este problema"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n3. Descomponer el problema en problemas más pequeños y asumibles"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n4. Resolver o simplificar"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n5. Revisar y refactorizar"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"1. Entender el problema"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nPara ver si realmente entendemos el problema podemos hacernos algunas preguntas básicas:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n* ¿Puedo replantear el problema con mis propias palabras?"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n* ¿Cuáles son realmente los inputs?"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n* ¿Cuáles son los outputs que debería devolver la solución del problema?"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n* ¿La salida puede ser determinada con los elementos que recibe el problema?¿Tenemos toda la información que necesitamos para resolver el problema?"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n* ¿Como debo identificar los datos importantes que son parte del problema?"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Lo primero seria resolver preguntas de este tipo para poder hacernos una idea de lo que necesitamos y donde tenemos las mayores dificultades con este problema."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"2. Buscar ejemplos"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nSi no tenemos ejemplos con la entrada y los resultados que deberíamos obtener, podemos tener tests o historias de usuario, pero al final, necesitamos algún tipo de pista de que es lo que necesitamos conseguir."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nA continuación podemos plantearnos empezar creando nosotros mismos ejemplos simples (podemos incluso simplificar un poco el problema ignorando algunas de sus condiciones) e ir avanzando añadiendo dificultad hasta tener toda la complejidad que el problema realmente tiene. OJO no se nos pueden olvidar ejemplos con entras vacías o erroneas."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"3. Descomponer el problema"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nEn este punto debemos escribir los pasos que necesitamos tomar para resolver el problema, y sí "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"escribir"}]},{"type":"text","value":" aunque parezca una tontería esto nos ayuda a plantear la resolución del problema correctamente viendo posibles fallos en nuestro planteamiento antes de escribir una sola línea de código. Al escribir los pasos, los estamos descomponiendo en otros más pequeños que son más sencillos de enfrentar."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"4. Resolver el problema/Simplificando el problema"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nAhora llega el punto de realmente resolver el problema. A la hora de intentar resolverlo nos daremos cuenta donde realmente estará el núcleo de la difilcutad que tenemos para llegar a revolver el problema. En este punto lo que debemos hacer es ignorar esa dificultad, es decir, simplificamos el problema y lo resolvemos de esta manera. Una vez que esté resuelto volvemos a incorporar esa dificultad a nuestra solución."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nAunque no lo parezca, este proceso ayuda muchas veces a resolver nuestro problema."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"5. Revisar y refactorizar"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nEn este punto lo que tendríamos que hacer sería comprobar, lo primero, si nuestra solución realmente funciona en todos los casos y luego ya hacernos preguntas de este estilo:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n- ¿Podemos llegar a la misma solución de otra manera?"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n- ¿Podemos usar este algoritmo para resolver otros problemas?"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n- ¿Podemos mejorar el rendimiento de nuestra solución?"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n- ¿Cómo han resuelto el problema otros desarrolladores?"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Con un plan o estrategia similar a estos 5 puntos podemos acercarnos más a una solución a nuestro problema."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y a continuación esta estrategia la complementaremos con nuestro conocimiento en algunos patrones típicos de resolución de problemas."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"commonproblemsolvingpatterns"},"children":[{"type":"text","value":"Common problem solving patterns"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Existen multitud de patrones de resolución de problemas:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n- Frequency Counter"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n- Multiple Pointers"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n- Sliding Window"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n- Divide and Conquer"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n- Dynamic Programming"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n- Greedy Algorithms"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n- ...."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Aquí comentaremos algunos que están en el nivel correcto sencillez/utilidad pero en esta página "},{"type":"element","tagName":"a","properties":{"href":"https://www.geeksforgeeks.org/fundamentals-of-algorithms/"},"children":[{"type":"text","value":"GeeksForGeeks"}]},{"type":"text","value":" tenemos todos los patrones o algoritmos que podamos necesitar (es muy completa)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vamos a empezar viendo el que se conoce como "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Frequency Counter"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"patrnfrequencycounter"},"children":[{"type":"text","value":"Patrón FREQUENCY COUNTER"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Este patrón es relativamente sencillo y tiene una función muy específica "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"\"Contar las veces que algo se repite o aparece\""}]},{"type":"text","value":". En un primer momento podemos pensar en la utilidad de esto, veamoslo con un ejemplo."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Queremos un método que compruebe si un string es un "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"anagrama"}]},{"type":"text","value":" de otro, es decir, queremos saber si ambos strings se pueden formar con las mismas letras. Una forma fácil es contar las veces que existe cada letra en ambos strings y comparar, veremos dos acercamientos posibles de este patrón"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"validAnagram"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"string1"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" string2"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    \n    "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"//Comprobamos si el tamaño es el mismo,si no, terminamos antes de empezar"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"string1"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"length "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!=="}]},{"type":"text","value":" string2"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"length"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n    \n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" frequency1 "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" frequency2 "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"//Recorremos ambos strings y guardamos en un objeto siendo la letra la key y el valor el número de veces que aparece"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" char "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"of"}]},{"type":"text","value":" string1"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        frequency1"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"char"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"++"}]},{"type":"text","value":"frequency1"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"char"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"||"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n    \n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" char "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"of"}]},{"type":"text","value":" string2"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        frequency2"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"char"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"++"}]},{"type":"text","value":"frequency2"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"char"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"||"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n    "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"//Recorremos y comprobamos. Si en algún caso las cantidades no coinciden entonces no es un anagrama uno de otro"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" char "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"in"}]},{"type":"text","value":" frequency1"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        \n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"frequency1"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"char"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!=="}]},{"type":"text","value":" frequency2"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"char"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"true"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Esta es una solución válida, que excepto que tenemos 3 búcles for, no está mal. Veamos otro posible acercamiento en este caso son solo 2 búcles"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"validAnagram"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"string1"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" string2"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"//Comprobamos si el tamaño es el mismo,si no, terminamos antes de empezar"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"string1"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"length "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!=="}]},{"type":"text","value":" string2"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"length"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" letters "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    \n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" i "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" i "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":" string1"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"length"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" i"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"++"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        letters"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"string1"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"i"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"++"}]},{"type":"text","value":"letters"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"string1"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"i"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"||"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n    \n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" i "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" i "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":" string2"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"length"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" i"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"++"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"//Si es 0 o no existe no es un anagrama."}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"letters"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"string2"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"i"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"else"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n            letters"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"string2"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"i"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"-="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"true"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En este caso tenemos otra solución que tiene un búcle for menos y también nos funciona. Por si a alguien no le queda claro lo que estamos haciendo es restando las coincidencias del segundo string con el primero dentro de nuestro objeto letters y en el caso de que intentemos acceder a un valor que ya es 0 o que no exista es señal de que no es un anagrama."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bueno y hasta aquí el patrón de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Frequency Count"}]},{"type":"text","value":", básicamente contamos dentro de un objeto CLAVE-VALOR los elementos que nos interesen, sencillo ¿verdad?"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Nos vemos en el siguiente, un abrazooooooorrrrrrrr."}]},{"type":"text","value":"\n"},{"type":"comment","value":"kg-card-end: markdown"}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"resolucindeproblemas","heading":"Resolución de problemas","items":[{"id":"bestpractices","heading":"Best Practices","items":[{"id":"pasosbsicospararesolverunproblema","heading":"Pasos básicos para resolver un problema"}]},{"id":"commonproblemsolvingpatterns","heading":"Common problem solving patterns"},{"id":"patrnfrequencycounter","heading":"Patrón FREQUENCY COUNTER"}]}]},"featureImageSharp":{"base":"unordered-3192273_640.png","publicURL":"/static/e92df4805fb46ec1f6bec181d2305365/unordered-3192273_640.png","imageMeta":{"width":640,"height":512},"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFG0lEQVQ4ywEQBe/6APG/tx3SpZ5Y2+PkQNzf3UjCw89E2M6jZubUibvJxK5Yk5/RHmd0qxNMWpUXsLO/LLe5xT+corsvv7++MmxsaxaZmYUXj4+WHsrKyjrNzc1HANSJfnXTZVT/1X5wp7K+vUSttMg40cSUb+zYh97by4ie0smidOHVpIbbzpWb7Nybsuvbmrbd0ZKAnp/khImK5tyWltuK4uHGPOXl6E3NyMdIAJFqZDnPkIiCwW5inMx1abl/j3YbtLb/AOjCOwXl1IRn2MmFntzNk5Tw46uQ493CYMS+olvt2X+avrSnpo6R6KCEhNulmZrkhs3SsikAABILAMfLzkae0MIY/6TMANl3X5vGi5ajeYjzhYiH66WJi+eaq7TzQuTZqG3v3I+008OFfpKk8ie0pm0n792VubCzwjPOzcE9hofluLOt43/Ue2F8ANfWxzZsXLEeh5X/UKZvjFq/eo3ml6HgedPLukaUk+KxjIvdlPnhcoXu2pwW6tWCl8/Iq1Lp15Cv5NacgElUgxje2r4yvcLqYZeH0tfZdGPhALu70USCg+mpgobwgoyG49zFeobjqqbhhYCO6YmDh+SynZ3VX+bUg4Dq1oeN7NiHxOjXj8jk0XNXfoaCFL29wE7Lx8dK0eznLZB8yaHSgH3MAJuc5qKGhuCF3tmJGo2S6rLIdnrJpYq+sLCIr8LKrbdquMG3RJuZo0vHu4eC6NeQy9HPwUuJjNporKzXYbuzoTe1uLtHuLe0P9BrY8C/fYF/AI+Q58Kur9NhvLfDQ3+K8pXFeW9m3nJZ2d1mRoLUb1ydv8HBKcPc+Cu1qoeG8+med5KY8HOYl+bKjo3nvwBn/w6J0MgV1nhjuayBsuFPctxCAIqK7qybm8txAAAAAXyG8Im3kraj2nBY0M9vZazlcWFlAAAADkseE59cLiD4TiMHc3570auip+BMkJnslKZ3q5PXYkie0GhZ4bR9ntm4na5oAIeJ4GGOj+7S1dDJTqe951G3e5nrx2pZTs2/pT+ZjH9IUSohtkYkGP9XJBf/WCIR/1gwNfV2ds+lv3SH1M97csHfiWiGynJ1za10ncfifGW3AOvajLKkn8qdgYLtx7LA8WbegnGkmn2+vJKn/39iRVHMXjcn/z87N/l/ZFP7OSol/0MsHrvEbG2usHef4ouY+aGJnvF1rn+ozdF3ccLMeGqWAOzZjN7444OryLyvuH2K+8C8iZ/U1IJ2oG+u/zB5ZHl8iHBd/6eWifvKqI3/npGF/ZR5bf/EbW3an7DGK6Sl5YuLiuf/jZb2obahhjO1vMJGAPLflS795oUW9+N/ld/QjMXYyJr43I1t9MdNJzUAOAADpodx58Gfh/+2pJbpw6GH+qSGc9rPblisqpfDcKWj1N7m2KHVo57Myri4vFCtpqwTAP///wA4Qu8NgYTuetbLs6rk1pb/ybOjt9VvZ6nCe3R8vZ6Dvph6YsCjhXPzi3FcsbWUgL/SalawjoTgrpufzW7YypGa3c+i5uvbk3jw34+GANDPuTesrNtxi4zo4oqN87bDubTD5NiUt9zOonzEh23DnoF+8JF8gsfRpHz/jndr07mIdvXMfGaGn6TvrJiW2L23sMDh18qbg8urAAXq2pGqANDQ0EM2NjUTeHidH5qZlSEABVkJ/+eDL9fJh43Hpn/zn4ym/6Ca0f+tnbD+nYaO/7eXhvmxroxy7N6gf8u/p57XzJ513+DcQ7e3uzE9PDMO7sYRFrnPY/gAAAAASUVORK5CYII=","aspectRatio":1.25,"src":"/static/e92df4805fb46ec1f6bec181d2305365/8bef3/unordered-3192273_640.png","srcSet":"/static/e92df4805fb46ec1f6bec181d2305365/847ef/unordered-3192273_640.png 175w,\n/static/e92df4805fb46ec1f6bec181d2305365/91cba/unordered-3192273_640.png 350w,\n/static/e92df4805fb46ec1f6bec181d2305365/8bef3/unordered-3192273_640.png 640w","srcWebp":"/static/e92df4805fb46ec1f6bec181d2305365/1ea2e/unordered-3192273_640.webp","srcSetWebp":"/static/e92df4805fb46ec1f6bec181d2305365/9fca7/unordered-3192273_640.webp 175w,\n/static/e92df4805fb46ec1f6bec181d2305365/37a4e/unordered-3192273_640.webp 350w,\n/static/e92df4805fb46ec1f6bec181d2305365/1ea2e/unordered-3192273_640.webp 640w","sizes":"(max-width: 640px) 100vw, 640px"}}}},"next":{"id":"Ghost__Post__5be93e342dd6610fd828ca11","title":"Docker IV: Development Workflow","slug":"docker-iv-development-workflow","featured":false,"feature_image":"https://jlgarcia.fulldev.ninja/assets/images/2018/12/docker_facebook_share-3.png","excerpt":"La idea es ir empezando a ver como sería un entorno real de desarrollo con\nDocker teniendo:\n\n * Nuestro entorno de desarrollo: Un entorno donde creamos las cosas.\n * Entorno de test: Tras el desarrollo, pasamos nuestro código al entorno de\n   test donde, como su propio nombre indica, probamos que todo funciona.\n * Entorno de producción: Tras pasar los tests pertinentes automáticamente el\n   proyecto pasaría a producción.\n\nEste workflow es lo que comunmente se conoce como Integración Continua,\nCo","custom_excerpt":null,"visibility":"public","created_at_pretty":"12 Nov 2018","published_at_pretty":"1 Oct 2018","updated_at_pretty":"19 Jan 2021","created_at":"2018-11-12T09:47:48.000+01:00","published_at":"2018-10-01T12:33:00.000+02:00","updated_at":"2021-01-19T20:50:35.000+01:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"Perfil.jpg","publicURL":"/static/b0de6281fb28a266510b3b09b9243e5a/Perfil.jpg","imageMeta":{"width":307,"height":307},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUDBAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGzw6zC6zHn+cLYP//EAB0QAAICAQUAAAAAAAAAAAAAAAEDAAIEEyEiIzL/2gAIAQEAAQUCifca8KgcKWVfUpkHsG5pxX//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAdEAACAgEFAAAAAAAAAAAAAAAAARARcQISIUFR/9oACAEBAAY/AhU88xkb7N06a8P/xAAcEAEAAwEAAwEAAAAAAAAAAAABABEhMUFRYXH/2gAIAQEAAT8hR2pq40aqb+xIAeXibhW9JXr8joF4TBcSNe0//9oADAMBAAIAAwAAABDzDwD/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAcEAEAAgIDAQAAAAAAAAAAAAABABEhUTFhcfD/2gAIAQEAAT8QyItrELaTlatLwU63MvEW6vUNdy4LZQDn7iVApV9VLtANdWwKkuYq4Er1VZ//2Q==","aspectRatio":1,"src":"/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg","srcSet":"/static/b0de6281fb28a266510b3b09b9243e5a/f340b/Perfil.jpg 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/22d64/Perfil.jpg 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/aa249/Perfil.jpg 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/0dc33/Perfil.jpg 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/60667/Perfil.jpg 307w","srcWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp","srcSetWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/59cda/Perfil.webp 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/7da75/Perfil.webp 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f282e/Perfil.webp 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/a7b21/Perfil.webp 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f59af/Perfil.webp 307w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"docker","url":"https://jlgarcia.fulldev.ninja/tag/docker/","name":"Docker","visibility":"public","feature_image":null,"description":null,"meta_title":"Docker Issues","meta_description":"Veremos algunos de los problemas que me he ido encontrando trabajando con contenedores y que no es tan fácil encontrar la solución en internet.","featureImageSharp":null},"tags":[{"slug":"docker","url":"https://jlgarcia.fulldev.ninja/tag/docker/","name":"Docker","visibility":"public","feature_image":null,"description":null,"meta_title":"Docker Issues","meta_description":"Veremos algunos de los problemas que me he ido encontrando trabajando con contenedores y que no es tan fácil encontrar la solución en internet.","featureImageSharp":null}],"plaintext":"La idea es ir empezando a ver como sería un entorno real de desarrollo con\nDocker teniendo:\n\n * Nuestro entorno de desarrollo: Un entorno donde creamos las cosas.\n * Entorno de test: Tras el desarrollo, pasamos nuestro código al entorno de\n   test donde, como su propio nombre indica, probamos que todo funciona.\n * Entorno de producción: Tras pasar los tests pertinentes automáticamente el\n   proyecto pasaría a producción.\n\nEste workflow es lo que comunmente se conoce como Integración Continua,\nContinuous Integration o CI. Para este proceso usaremos herramientas o servicios\ncomo Github o Travis CI y desarrollaremos con ReactJS (no importa que no sepamos\nusarlos veremos lo necesario para entender lo que estamos haciendo).\n\nEntorno de desarrollo\nEmpecemos por el primero de los entornos, el entorno de desarrollo. Lo que\nbuscamos en este entorno es que nuestros cambios mientras estamos desarrollando\nse sincronicen automáticamente con el contenedor de desarrollo (esto en varios\ncasos es innecesario pero lo veremos igualmente con los fines didácticos que nos\nocupan).\nPensando en el objetivo de este entorno, ya hemos visto que si realizamos\ncambios en nuestro código tenemos que volver a realizar un build y luego\narrancar un contenedor nuevo con la imagen que nos crearía el build anterior.\nEsto realmente no es lo que estamos buscando, es poco eficiente y tendríamos\ndemasiadas imágenes de contenedor.\n\nEn docker existe una forma de solucionar esto, vamos a introducir algo que no\nhemos visto todavia: Los Volúmenes.\nEn docker un volumen no deja de ser una referencia al filesystem del contenedor\ny puede ser una referencia, como un mapeo (al igual que los puertos) de una\ncarpeta local a una del contenedor, o un 'no lo toques' (que básicamente es\nmapea todo menos esto). Lo vamos a probar directamente, primero de todo vamos\npreparar un proyecto para trabajar con el, empecemos por crearnos un proyecto de\nReactJS.\n\nPara trabajar con react usaremos un paquete de npm que nos instala un proyecto\nbásico inicial, lo instalamos con\n\nnpm -g install create-react-app\n\n\nUna vez instalado ya podríamos crearnos un proyecto\n\ncreate-react-app frontWeb\n\n\nEsto nos creará un proyecto de react dentro de una carpeta llamada frontWeb.\nPara probar si funciona solo tenemos que entrar en la carpeta y ejecutar con:\n\nnpm start\n\n\n\n\nBien ya tenemos nuestra web de react, vamos ahora con la parte del entorno de \ndesarrollo de docker.\nPara ejecutar nuestro entorno de desarrollo en un contenedor solo necesitamos\nque tenga node instalado, es decir, que es similar a lo que hemos creado\nanteriormente.\n\nAntes de continuar comentar que aunque vamos a trabajar casi todo el rato con\ncomandos de docker-compose todo lo que hagamos a partir de ahora se puede hacer\ncon comandos docker run también, pero realmente son comandos muy largos y poco\nútiles a la larga. En caso de necesidad siempre podemos buscar cual es el flag\ndel comando para ponerlo directamente sin usar un dockerfile.\n\nContinuemos, volvamos al principio, hemos dicho que queríamos un entorno de\ndesarrollo donde nuestro contenedor se actualice automáticamente según vayamos\nhaciendo cambios en local, para ello vamos a hacer uso de lo que en docker se\nconoce como volumenes.\nLo primero nos crearemos dentro de nuestra carpeta de proyecto de react un\nfichero dockerfile pero esta vez pondremos:\n\nDockerfile.dev\n\n\nComo es normal aunque no lo hayamos visto a docker se le puede indicar el\nfichero dockerfile a usar cuando hacemos un build, solo tenemos que usar el flag \n-f, por ejemplo (ojo al punto del final)\n\ndocker build -f ./Dockerfile.dev .\n\n\nLo mismo con los ficheros para docker-compose, por lo que realmente no tendremos\nningún problema y podemos tener varios dockerfile distintos según nuestro\nentorno.\nSabiendo esto continuamos con nuestro fichero Dockerfile.dev\n\nFROM node:alpine\n\nWORKDIR '/app'\n\nCOPY package.json .\nRUN npm install\n\nCOPY . .\n\nCMD [\"npm\", \"start\"]\n\n\nMisma teoria que anteriormente, copiamos el package.json primero por posibles\ncambios solo del resto y no tener que hacer otra vez el npm install todo el rato\ncada vez que hagamos un build.\nYa tenemos nuestro fichero dockerfile, ahora como la idea es usar docker-compose \npara todo necesitamos crear el fichero docker-compose.yml\n\nversion: '3'\nservices:\n    web_react:\n        build: \n            context: .\n            dockerfile: Dockerfile.dev\n        ports:\n            - \"3000:3000\"\n\n\nAntes de continuar, vemos que ahora donde tenemos puesto build ahora hemos\nañadido 2 propiedades:\n\n * context: Indicamos el contexto desde(path) desde el que trabajara el build\n   del docker-compose.\n * dockerfile: Nombre del fichero dockerfile que queremos usar.\n\nContinuemos, ahora vamos a hablar del concepto de Volume (por fin ;) ), primero\nañadamoslo al fichero\n\nversion: '3'\nservices:\n    web_react:\n        build: ./Dockerfile.dev\n        ports:\n            - \"3000:3000\"\n        volumes:\n            - /app/node_modules\n            - .:/app\n\n\nSi nos fijamos en lo que hemos puesto, tenemos realmente dos conceptos distintos\ndentro de volumes:\n\n * .:/app: Hablemos primero del segundo, este es similar al concepto de mapear\n   puertos, básicamente le estamos indicando que mapee todo el contenido de la\n   ruta actual de mi equipo local, al path /app del contenedor, lo que\n   funcionaría similar a un acceso directo a los ficheros de la carpeta local de\n   nuestro equipo.\n * /app/node_modules: Si nos fijamos en esta línea no tenemos ':', eso es porque\n   aquí le estamos indicando que haga como un marcador de la carpeta \n   node_modules del contenedor, es decir, usa la del contenedor, no la toques y\n   dejala donde está (esto hace que la carpeta se mantenga aunque hagamos el\n   paso anterior).\n\nAhora que ya sabemos lo que hemos puesto, viene la pregunta del ¿por\nqué?....bien, si pensamos en el proceso que hemos añadido en el Dockerfile.dev,\ntenemos una parte donde instalamos los paquetes que están indicados en el \npackage.json, es decir, queremos que los descargues e instales de nuevo cuando\nhagamos un build de la imagen del contenedor, y no pasamos la carpeta local \nnode_modules (que es donde instala las dependencias), que de hecho la vamos a\neliminar para que veamos como funciona, si, eliminarla.\n\nYa que hablamos del Dockerfile.dev, alguno se puede preguntar si hacemos la\nrefencia o linkado de nuestra carpeta local, ¿para qué hacemos el\nCOPY?....bueno, esto es para prevenir creaciones para producción usando los\nmismos Dockerfiles, realmente en nuestro caso actual no lo necesitamos pero para\nproducción siempre es mejor para evitar errores, ya que un contenedor en\nproducción NO DEBE hacer referencias a carpetas locales de ningún sitio solo\ntiene que tener sus propios ficheros.\n\nYa tenemos todo ahora nos situamos en la ruta donde tenemos el fichero \ndocker-compose.yml y ejecutamos:\n\ndocker-compose up\n\n\nSi todo va bien deberíamos ver algo como esto en la consola\n\n\nY si accedemos en el navegador a:\n\nlocalhost:3000\n\n\nDeberíamos ver\n\n\n\nBien como tal ya tenemos todo funcionando, pero realmente lo que queremos es\npoder desarrollar en local y que se actualice el contenedor , ¿no?... pues vamos\na probarlo.\nNos vamos a nuestra web de react, y dentro de la carpeta src modificamos el\nfichero App.js y ponemos lo que queramos:\n\n <div className=\"App\">\n        <header className=\"App-header\">\n          <img src={logo} className=\"App-logo\" alt=\"logo\" />\n          <p>\n            Hola ninjaaaaasssss\n          </p> //<-- Esta es la linea que cambiamos\n          <a\n            className=\"App-link\"\n            href=\"https://reactjs.org\"\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n          >\n            Learn React\n          </a>\n        </header>\n      </div>\n\n\nY una vez que guardemos el documento automáticamente se debería actualizar el\nnavegador y mostrar\n\n\n\n¡¡¡PERFECTO!!!... ya tenemos nuestro entorno de desarrollo funcionando.\n\nEmpecemos con el entorno de TEST\n\nTEST\nPor defecto react viene ya configurado con 1 test para poder probar, solo\ntenemos que hacer\n\nnpm run test\n\n\no\n\nnpm test\n\n\ny automáticamente nos pasaría los tests\n\n\n\nBien, pues ahora queremos esto pero en un contenedor, como opción rápida podemos\nejecutar una imagen creada con el mismo dockerfile pero cambiando el comando de\narranque (esto es solo para que veais que funciona).\n\nPor si no la tenemos creamos el build de la imagen, yo la voy a taggear para\npoder identificarla\n\ndocker build -f ./Dockerfile.dev . -t test_react\n\n\nEsto nos devuelve una imagen con ese nombre\n\n\n\nYa la tenemos, ahora solo vamos a realizar un run habitual cambiando el comando\nde arranque\n\ndocker run -it test_react npm test\n\n\nLe he añadido -it para poder trabajar con la consola de test y como algo nuevo\nsi nos fijamos hemos puesto cosas tras el nombre de la imagen, básicamente todo\nlo que ponemos a continuación del nombre de la imagen a ejecutar lo toma como\ncomando de arranque para el contenedor. Si lo ejecutamos nos devuelve\n\n\nOtra opción es añadirlo a nuestro docker-compose añadiendo otro servicio pero\ncon la misma teoría, compartiendo o mapeando ficheros entre el equipo local y el\ncontenedor, teniendo 2 contenedores funcionando uno para las pruebas en\ndesarrollo y otro probando los test. El problema de este acercamiento es que no\ntenemos control sobre la consola de test por lo que no podemos hacer mucho más\nque ver como pasan los tests cada vez que hacemos un cambio en los ficheros.\nVamos a probarlo, cambiamos nuestro fichero docker-compose\n\nversion: '3'\nservices:\n    web_react:\n        build:\n            context: .\n            dockerfile: Dockerfile.dev\n        ports:\n            - \"3000:3000\"\n        volumes:\n            - /app/node_modules\n            - .:/app\n    test_react:\n        build:\n            context: .\n            dockerfile: Dockerfile.dev\n        volumes:\n            - /app/node_modules\n            - .:/app\n        command: [\"npm\",\"test\"]\n\n\nComo véis hemos añadido otro servicio (contenedor ya sabéis), en este caso se\nllama test_react, que usa el mismo dockerfile y mapea de la misma forma los \nvolumenes. Despues de eso si que tiene cambios, hemos quitado el mapeo del\npuerto porque ya no lo necesitamos y como extra nuevo hemos añadido la propiedad \ncommand que básicamente lo que hace es cambiar el comando de inicio del\ncontenedor.\nA continuación si ejecutamos nuestro docker-compose up, nos crea dos\ncontenedores y como podremos ver el log ambos funcionan correctamente, y si\ncambiamos algo en los ficheros se actualizan ambos, tanto el de desarrollo como\nel que pasa los tests.\n\n\n\nNinguno de los casos es muy ideal pero son funcionales y puede que en algún caso\nnos pueda servir para algo, más adelante veremos un entorno de test más 'real'\npor el momento esto es más que suficiente, a continuación empezaremos a hablar\nun poco de PRODUCCIÓN\n\nPRODUCCIÓN\nPasemos ahora a producción, la intención es crear un contenedor que nos devuelva\nnuestra aplicación ya preparada para producción, para el que no lo sepa, una app\nde react la preparamos para producción ejecutando el comando:\n\nnpm run build\n\n\nY este comando nos deja unos ficheros típicos de web (html, js y css), es decir, \nficheros estáticos. Estos ficheros los deja en una carpeta llamada build dentro\nde nuestro proyecto.\n\nAhora necesitamos para producción un servidor web, los más utilizados son Apache\no Nginx, aunque podríamos hacerlo con NodeJS, Go, Ruby, etc..... con casi todos\nlos lenguajes tenemos alguna opción para hacerlo. En nuestro caso usaremos un\ncontenedor con Nginx.\n\nSi miramos la documentación del contenedor oficial\n[https://hub.docker.com/_/nginx/] podemos ver que los ficheros los sirve desde\nel path /usr/share/nginx/html. Sabiendo esto entonces básicamente lo que\ntendriamos que hacer sería copiar nuestros ficheros de producción en esa ruta\ndel contenedor de nginx... pero claro se supone que no tenemos en local los\narchivos, veamos como podemos hacerlo con el entorno que tenemos ahora.\n\nNos vamos a crear un nuevo dockerfile con esto\n\nFROM node:alpine as builder\nWORKDIR '/app'\nCOPY package.json .\nRUN npm install\nCOPY . .\nRUN npm run build\n\nFROM nginx\nCOPY --from=builder /app/build /usr/share/nginx/html\n\n\nEmpecemos por la primera linea:\n\nFROM node:alpine as builder\n\n\nIntroducimos algo nuevo en este punto, básicamente lo que estamos haciendo es\nindicarle al proceso que añada como una referencia al resultado del build de ese\ncontenedor con nombre builder, pero puede ser cualquier otro. Esta referencia\nsolo está disponible en el contexto de la ejecución de docker build.\nEl resto del primer contenedor es algo que ya hemos visto, vayamos con el\nsegundo\n\nFROM nginx\nCOPY --from=builder /app/build /usr/share/nginx/html\n\n\nAquí empezamos con el segundo contenedor. Vemos como la instrucción COPY tiene\nalgo nuevo\n\n--from=builder\n\n\nComo os podéis imaginar tiene que ver con la instrucción as builder del primer\ncontenedor, aquí le estamos diciendo que del primer contenedor se copie la ruta \n/app/build y la pegue en /usr/share/nginx/html\nBien pues vamos a ejecutar nuestro nuevo build\n\ndocker build .\n\n\nUna vez terminado\n\n\n\nTenemos ya construido una imagen con supuestamente nginx y nuestra app en\nproducción. Por último nos faltaría crear un contenedor con esa imagen, pues\nvamos a ello\n\ndocker run -p 3500:80 --name webpro idImagen\n\n\nComo extra he añadido --name que lo que hace es taggearnos el contenedor con un\nnombre que podamos gestionar de manera más comoda que un ID numérico\n\n\n\nSe puede ver al principio el comando y a continuación un log (el de nginx) una\nvez que intentamos acceder a la página\n\n\n\nY como podemos ver ya tenemos nuestro entorno para producción que básicamente es\nel build del dockerfile una vez que hemos terminado de desarrollar.\n\nEn próximos posts veremos una forma más profesional de hacer todo esto con \nIntegración Continua gracias a TravisCI y GitHub.","html":"<!--kg-card-begin: markdown--><p>La idea es ir empezando a ver como sería un entorno real de desarrollo con Docker teniendo:</p>\n<ul>\n<li><strong>Nuestro entorno de desarrollo</strong>: Un entorno donde <em><strong>creamos</strong></em> las cosas.</li>\n<li><strong>Entorno de test</strong>: Tras el desarrollo, pasamos nuestro código al entorno de test donde, como su propio nombre indica, probamos que todo funciona.</li>\n<li><strong>Entorno de producción</strong>: Tras pasar los tests pertinentes automáticamente el proyecto pasaría a producción.</li>\n</ul>\n<p>Este <em>workflow</em> es lo que comunmente se conoce como <em>Integración Continua, Continuous Integration o CI</em>. Para este proceso usaremos herramientas o servicios como Github o Travis CI y desarrollaremos con ReactJS (no importa que no sepamos usarlos veremos lo necesario para entender lo que estamos haciendo).</p>\n<h3 id=\"entornodedesarrollo\">Entorno de desarrollo</h3>\n<p>Empecemos por el primero de los entornos, el entorno de desarrollo. Lo que buscamos en este entorno es que nuestros cambios mientras estamos desarrollando se <em>sincronicen</em> automáticamente con el contenedor de desarrollo  (esto en varios casos es innecesario pero lo veremos igualmente con los fines didácticos que nos ocupan).<br>\nPensando en el objetivo de este entorno, ya hemos visto que si realizamos cambios en nuestro código tenemos que volver a realizar un <em><strong>build</strong></em> y luego arrancar un contenedor nuevo con la imagen que nos crearía el build anterior. Esto realmente no es lo que estamos buscando, es poco eficiente y tendríamos demasiadas imágenes de contenedor.</p>\n<p>En docker existe una forma de solucionar esto, vamos a introducir algo que no hemos visto todavia: <strong>Los Volúmenes</strong>.<br>\nEn docker un <em>volumen</em> no deja de ser una referencia al filesystem del contenedor y puede ser una referencia, como un <em>mapeo</em> (al igual que los puertos) de una carpeta local a una del contenedor, o un 'no lo toques' (que básicamente es mapea todo menos esto). Lo vamos a probar directamente, primero de todo vamos preparar un proyecto para trabajar con el, empecemos por crearnos un proyecto de ReactJS.</p>\n<p>Para trabajar con react usaremos un paquete de npm que nos instala un proyecto básico inicial, lo instalamos con</p>\n<pre><code class=\"language-shell\">npm -g install create-react-app\n</code></pre>\n<p>Una vez instalado ya podríamos crearnos un proyecto</p>\n<pre><code>create-react-app frontWeb\n</code></pre>\n<p>Esto nos creará un proyecto de react dentro de una carpeta llamada frontWeb. Para probar si funciona solo tenemos que entrar en la carpeta y ejecutar con:</p>\n<pre><code class=\"language-shell\">npm start\n</code></pre>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture.JPG\" alt=\"Capture\"></p>\n<p>Bien ya tenemos nuestra web de react, vamos ahora con la parte del entorno de <em>desarrollo</em> de docker.<br>\nPara ejecutar nuestro entorno de desarrollo en un contenedor solo necesitamos que tenga <strong>node</strong> instalado, es decir, que es similar a lo que hemos creado anteriormente.</p>\n<p>Antes de continuar comentar que aunque vamos a trabajar casi todo el rato con comandos de <strong>docker-compose</strong> todo lo que hagamos a partir de ahora se puede hacer con comandos <strong>docker run</strong> también, pero realmente son comandos muy largos y poco útiles a la larga. En caso de necesidad siempre podemos buscar cual es el flag del comando para ponerlo directamente sin usar un <strong>dockerfile</strong>.</p>\n<p>Continuemos, volvamos al principio, hemos dicho que queríamos un entorno de desarrollo donde nuestro contenedor se actualice automáticamente según vayamos haciendo cambios en local, para ello vamos a hacer uso de lo que en docker se conoce como <em>volumenes</em>.<br>\nLo primero nos crearemos dentro de nuestra carpeta de proyecto de react un fichero <em>dockerfile</em> pero esta vez pondremos:</p>\n<pre><code class=\"language-shell\">Dockerfile.dev\n</code></pre>\n<p>Como es normal aunque no lo hayamos visto a docker se le puede indicar el fichero <em>dockerfile</em> a usar cuando hacemos un build, solo tenemos que usar el flag <strong>-f</strong>,  por ejemplo (ojo al punto del final)</p>\n<pre><code class=\"language-shell\">docker build -f ./Dockerfile.dev .\n</code></pre>\n<p>Lo mismo con los ficheros para <strong>docker-compose</strong>, por lo que realmente no tendremos ningún problema y podemos tener varios <em>dockerfile</em> distintos según nuestro entorno.<br>\nSabiendo esto continuamos con nuestro fichero <strong>Dockerfile.dev</strong></p>\n<pre><code class=\"language-docker\">FROM node:alpine\n\nWORKDIR '/app'\n\nCOPY package.json .\nRUN npm install\n\nCOPY . .\n\nCMD [&quot;npm&quot;, &quot;start&quot;]\n</code></pre>\n<p>Misma teoria que anteriormente, copiamos el package.json primero por posibles cambios solo del resto y no tener que hacer otra vez el <em>npm install</em> todo el rato cada vez que hagamos un build.<br>\nYa tenemos nuestro fichero <em>dockerfile</em>, ahora como la idea es usar <em>docker-compose</em> para todo necesitamos crear el fichero docker-compose.yml</p>\n<pre><code class=\"language-yaml\">version: '3'\nservices:\n    web_react:\n        build: \n            context: .\n            dockerfile: Dockerfile.dev\n        ports:\n            - &quot;3000:3000&quot;\n</code></pre>\n<p>Antes de continuar, vemos que ahora donde tenemos puesto <em>build</em> ahora hemos añadido 2 propiedades:</p>\n<ul>\n<li><strong>context</strong>: Indicamos el contexto desde(path) desde el que trabajara el build del docker-compose.</li>\n<li><strong>dockerfile</strong>: Nombre del fichero dockerfile que queremos usar.</li>\n</ul>\n<p>Continuemos, ahora vamos a hablar del concepto de <strong>Volume</strong> (por fin ;) ), primero añadamoslo al fichero</p>\n<pre><code class=\"language-yaml\">version: '3'\nservices:\n    web_react:\n        build: ./Dockerfile.dev\n        ports:\n            - &quot;3000:3000&quot;\n        volumes:\n            - /app/node_modules\n            - .:/app\n</code></pre>\n<p>Si nos fijamos en lo que hemos puesto, tenemos realmente dos conceptos distintos dentro de <em>volumes</em>:</p>\n<ul>\n<li><strong>.:/app</strong>: Hablemos primero del segundo, este es similar al concepto de mapear puertos, básicamente le estamos indicando que <em>mapee</em> todo el contenido de la ruta actual de mi equipo local, al path <em>/app</em> del contenedor, lo que funcionaría similar a un acceso directo a los ficheros de la carpeta local de nuestro equipo.</li>\n<li><strong>/app/node_modules</strong>: Si nos fijamos en esta línea no tenemos <strong>':'</strong>, eso es porque aquí le estamos indicando que haga como un <em>marcador</em> de la carpeta <em>node_modules</em> del contenedor, es decir, usa la del contenedor, no la toques y dejala donde está (esto hace que la carpeta se mantenga aunque hagamos el paso anterior).</li>\n</ul>\n<p>Ahora que ya sabemos lo que hemos puesto, viene la pregunta del ¿por qué?....bien, si pensamos en el proceso que hemos añadido en el <strong>Dockerfile.dev</strong>, tenemos una parte donde instalamos los paquetes que están indicados en el <em>package.json</em>, es decir, queremos que los descargues e instales de nuevo cuando hagamos un build de la imagen del contenedor, y no pasamos la carpeta local <em>node_modules</em> (que es donde instala las dependencias), que de hecho la vamos a eliminar para que veamos como funciona, si, <strong>eliminarla</strong>.</p>\n<p>Ya que hablamos del <strong>Dockerfile.dev</strong>, alguno se puede preguntar si hacemos la refencia o linkado de nuestra carpeta local, ¿para qué hacemos el COPY?....bueno, esto es para prevenir creaciones para producción usando los mismos Dockerfiles, realmente en nuestro caso actual no lo necesitamos pero para producción siempre es mejor para evitar errores, ya que un contenedor en producción <strong>NO DEBE</strong> hacer referencias a carpetas locales de <strong>ningún sitio</strong> solo tiene que tener sus propios ficheros.</p>\n<p>Ya tenemos todo ahora nos situamos en la ruta donde tenemos el fichero <em>docker-compose.yml</em> y ejecutamos:</p>\n<pre><code class=\"language-shell\">docker-compose up\n</code></pre>\n<p>Si todo va bien deberíamos ver algo como esto en la consola<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Captura-de-pantalla-2018-11-14-a-las-9.35.40.png\" alt=\"Captura-de-pantalla-2018-11-14-a-las-9.35.40\"></p>\n<p>Y si accedemos en el navegador a:</p>\n<pre><code class=\"language-shell\">localhost:3000\n</code></pre>\n<p>Deberíamos ver</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Captura-de-pantalla-2018-11-14-a-las-9.37.02.png\" alt=\"Captura-de-pantalla-2018-11-14-a-las-9.37.02\"></p>\n<p>Bien como tal ya tenemos todo funcionando, pero realmente lo que queremos es poder desarrollar en local y que se actualice el contenedor , ¿no?... pues vamos a probarlo.<br>\nNos vamos a nuestra web de react, y dentro de la carpeta <em>src</em> modificamos el fichero <em>App.js</em> y ponemos lo que queramos:</p>\n<pre><code class=\"language-html\"> &lt;div className=&quot;App&quot;&gt;\n        &lt;header className=&quot;App-header&quot;&gt;\n          &lt;img src={logo} className=&quot;App-logo&quot; alt=&quot;logo&quot; /&gt;\n          &lt;p&gt;\n            Hola ninjaaaaasssss\n          &lt;/p&gt; //&lt;-- Esta es la linea que cambiamos\n          &lt;a\n            className=&quot;App-link&quot;\n            href=&quot;https://reactjs.org&quot;\n            target=&quot;_blank&quot;\n            rel=&quot;noopener noreferrer&quot;\n          &gt;\n            Learn React\n          &lt;/a&gt;\n        &lt;/header&gt;\n      &lt;/div&gt;\n</code></pre>\n<p>Y una vez que guardemos el documento automáticamente se debería actualizar el navegador y mostrar</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Captura-de-pantalla-2018-11-14-a-las-9.40.32.png\" alt=\"Captura-de-pantalla-2018-11-14-a-las-9.40.32\"></p>\n<p>¡¡¡PERFECTO!!!... ya tenemos nuestro entorno de desarrollo funcionando.</p>\n<p>Empecemos con el entorno de <strong>TEST</strong></p>\n<h4 id=\"test\">TEST</h4>\n<p>Por defecto react viene ya configurado con 1 test para poder probar, solo tenemos que hacer</p>\n<pre><code class=\"language-shell\">npm run test\n</code></pre>\n<p>o</p>\n<pre><code class=\"language-shell\">npm test\n</code></pre>\n<p>y automáticamente nos pasaría los tests</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-1.JPG\" alt=\"Capture-1\"></p>\n<p>Bien, pues ahora queremos esto pero en un contenedor, como opción rápida podemos ejecutar una imagen creada con el mismo <em>dockerfile</em> pero cambiando el comando de arranque (esto es solo para que veais que funciona).</p>\n<p>Por si no la tenemos creamos el build de la imagen, yo la voy a <em>taggear</em> para poder identificarla</p>\n<pre><code class=\"language-shell\">docker build -f ./Dockerfile.dev . -t test_react\n</code></pre>\n<p>Esto nos devuelve una imagen con ese nombre</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-2.JPG\" alt=\"Capture-2\"></p>\n<p>Ya la tenemos, ahora solo vamos a realizar un <em>run</em> habitual cambiando el comando de arranque</p>\n<pre><code class=\"language-shell\">docker run -it test_react npm test\n</code></pre>\n<p>Le he añadido <em>-it</em> para poder trabajar con la consola de test y como algo nuevo si nos fijamos hemos puesto <em>cosas</em> tras el nombre de la imagen, básicamente todo lo que ponemos a continuación del nombre de la imagen a ejecutar lo toma como comando de arranque para el contenedor. Si lo ejecutamos nos devuelve<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-3.JPG\" alt=\"Capture-3\"></p>\n<p>Otra opción es añadirlo a nuestro <em>docker-compose</em> añadiendo otro servicio pero con la misma teoría, compartiendo o <em>mapeando</em> ficheros entre el equipo local y el contenedor, teniendo 2 contenedores funcionando uno para las pruebas en desarrollo y otro probando los test. El problema de este acercamiento es que no tenemos control sobre la consola de test por lo que no podemos hacer mucho más que ver como pasan los tests cada vez que hacemos un cambio en los ficheros.<br>\nVamos a probarlo, cambiamos nuestro fichero <em>docker-compose</em></p>\n<pre><code class=\"language-yaml\">version: '3'\nservices:\n    web_react:\n        build:\n            context: .\n            dockerfile: Dockerfile.dev\n        ports:\n            - &quot;3000:3000&quot;\n        volumes:\n            - /app/node_modules\n            - .:/app\n    test_react:\n        build:\n            context: .\n            dockerfile: Dockerfile.dev\n        volumes:\n            - /app/node_modules\n            - .:/app\n        command: [&quot;npm&quot;,&quot;test&quot;]\n</code></pre>\n<p>Como véis hemos añadido otro servicio (contenedor ya sabéis), en este caso se llama <strong>test_react</strong>, que usa el mismo <em>dockerfile</em> y mapea de la misma forma los <em>volumenes</em>. Despues de eso si que tiene cambios, hemos quitado el <em>mapeo</em> del puerto porque ya no lo necesitamos y como extra nuevo hemos añadido la propiedad <strong>command</strong> que básicamente lo que hace es cambiar el comando de inicio del contenedor.<br>\nA continuación si ejecutamos nuestro <em>docker-compose up</em>, nos crea dos contenedores y como podremos ver el log ambos funcionan correctamente, y si cambiamos algo en los ficheros se actualizan ambos, tanto el de desarrollo como el que pasa los tests.</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-4.JPG\" alt=\"Capture-4\"></p>\n<p>Ninguno de los casos es muy <strong>ideal</strong> pero son funcionales y puede que en algún caso nos pueda servir para algo, más adelante veremos un entorno de test más 'real' por el momento esto es más que suficiente, a continuación empezaremos a hablar un poco de <strong>PRODUCCIÓN</strong></p>\n<h4 id=\"produccin\">PRODUCCIÓN</h4>\n<p>Pasemos ahora a <em>producción</em>, la intención es crear un contenedor que nos devuelva nuestra aplicación ya preparada para producción, para el que no lo sepa, una app de react la preparamos para producción ejecutando el comando:</p>\n<pre><code class=\"language-shell\">npm run build\n</code></pre>\n<p>Y este comando nos deja unos ficheros típicos de web (html, js y css), es decir, <em>ficheros estáticos</em>. Estos ficheros los deja en una carpeta llamada <strong>build</strong> dentro de nuestro proyecto.</p>\n<p>Ahora necesitamos para producción un <em>servidor web</em>, los más utilizados son <strong>Apache o Nginx</strong>, aunque podríamos hacerlo con NodeJS, Go, Ruby, etc..... con casi todos los lenguajes tenemos alguna opción para hacerlo. En nuestro caso usaremos un contenedor con Nginx.</p>\n<p>Si miramos la documentación del <a href=\"https://hub.docker.com/_/nginx/\">contenedor oficial</a> podemos ver que los ficheros los sirve desde el path <strong>/usr/share/nginx/html</strong>. Sabiendo esto entonces básicamente lo que tendriamos que hacer sería copiar nuestros ficheros de producción en esa ruta del contenedor de nginx... pero claro se supone que no tenemos en local los archivos, veamos como podemos hacerlo con el entorno que tenemos ahora.</p>\n<p>Nos vamos a crear un nuevo <strong>dockerfile</strong> con esto</p>\n<pre><code class=\"language-docker\">FROM node:alpine as builder\nWORKDIR '/app'\nCOPY package.json .\nRUN npm install\nCOPY . .\nRUN npm run build\n\nFROM nginx\nCOPY --from=builder /app/build /usr/share/nginx/html\n</code></pre>\n<p>Empecemos por la primera linea:</p>\n<pre><code>FROM node:alpine as builder\n</code></pre>\n<p>Introducimos algo nuevo en este punto, básicamente lo que estamos haciendo es indicarle al proceso que añada como una referencia al resultado del <em>build</em> de ese contenedor con nombre <em>builder</em>, pero puede ser cualquier otro. Esta referencia solo está disponible en el contexto de la ejecución de <em>docker build</em>.<br>\nEl resto del primer contenedor es algo que ya hemos visto, vayamos con el segundo</p>\n<pre><code class=\"language-docker\">FROM nginx\nCOPY --from=builder /app/build /usr/share/nginx/html\n</code></pre>\n<p>Aquí empezamos con el segundo contenedor. Vemos como la instrucción COPY tiene algo nuevo</p>\n<pre><code class=\"language-docker\">--from=builder\n</code></pre>\n<p>Como os podéis imaginar tiene que ver con la instrucción <em>as builder</em> del primer contenedor, aquí le estamos diciendo que del primer contenedor se copie la ruta <em>/app/build</em> y la pegue en <em>/usr/share/nginx/html</em><br>\nBien pues vamos a ejecutar nuestro nuevo build</p>\n<pre><code class=\"language-shell\">docker build .\n</code></pre>\n<p>Una vez terminado</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-5.JPG\" alt=\"Capture-5\"></p>\n<p>Tenemos ya construido una imagen con supuestamente <strong>nginx</strong> y nuestra app en producción. Por último nos faltaría crear un contenedor con esa imagen, pues vamos a ello</p>\n<pre><code class=\"language-shell\">docker run -p 3500:80 --name webpro idImagen\n</code></pre>\n<p>Como extra he añadido <strong>--name</strong> que lo que hace es <em>taggearnos</em> el contenedor con un nombre que podamos gestionar de manera más comoda que un ID numérico</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-6.JPG\" alt=\"Capture-6\"></p>\n<p>Se puede ver al principio el comando y a continuación un log (el de nginx) una vez que intentamos acceder a la página</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture2.JPG\" alt=\"Capture2\"></p>\n<p>Y como podemos ver ya tenemos nuestro entorno para producción que básicamente es el build del <em>dockerfile</em> una vez que hemos terminado de desarrollar.</p>\n<p>En próximos posts veremos una forma más profesional de hacer todo esto con <em>Integración Continua</em> gracias a <strong>TravisCI</strong> y <strong>GitHub</strong>.</p>\n<!--kg-card-end: markdown-->","url":"https://jlgarcia.fulldev.ninja/docker-iv-development-workflow/","canonical_url":null,"uuid":"182bbd23-305b-4f6d-9eaa-fabfb8003c51","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"5be93e342dd6610fd828ca11","reading_time":9,"send_email_when_published":false,"email_subject":null,"childHtmlRehype":{"html":"<!--kg-card-begin: markdown--><p>La idea es ir empezando a ver como sería un entorno real de desarrollo con Docker teniendo:</p>\n<ul>\n<li><strong>Nuestro entorno de desarrollo</strong>: Un entorno donde <em><strong>creamos</strong></em> las cosas.</li>\n<li><strong>Entorno de test</strong>: Tras el desarrollo, pasamos nuestro código al entorno de test donde, como su propio nombre indica, probamos que todo funciona.</li>\n<li><strong>Entorno de producción</strong>: Tras pasar los tests pertinentes automáticamente el proyecto pasaría a producción.</li>\n</ul>\n<p>Este <em>workflow</em> es lo que comunmente se conoce como <em>Integración Continua, Continuous Integration o CI</em>. Para este proceso usaremos herramientas o servicios como Github o Travis CI y desarrollaremos con ReactJS (no importa que no sepamos usarlos veremos lo necesario para entender lo que estamos haciendo).</p>\n<h3 id=\"entornodedesarrollo\">Entorno de desarrollo</h3>\n<p>Empecemos por el primero de los entornos, el entorno de desarrollo. Lo que buscamos en este entorno es que nuestros cambios mientras estamos desarrollando se <em>sincronicen</em> automáticamente con el contenedor de desarrollo  (esto en varios casos es innecesario pero lo veremos igualmente con los fines didácticos que nos ocupan).<br>\nPensando en el objetivo de este entorno, ya hemos visto que si realizamos cambios en nuestro código tenemos que volver a realizar un <em><strong>build</strong></em> y luego arrancar un contenedor nuevo con la imagen que nos crearía el build anterior. Esto realmente no es lo que estamos buscando, es poco eficiente y tendríamos demasiadas imágenes de contenedor.</p>\n<p>En docker existe una forma de solucionar esto, vamos a introducir algo que no hemos visto todavia: <strong>Los Volúmenes</strong>.<br>\nEn docker un <em>volumen</em> no deja de ser una referencia al filesystem del contenedor y puede ser una referencia, como un <em>mapeo</em> (al igual que los puertos) de una carpeta local a una del contenedor, o un 'no lo toques' (que básicamente es mapea todo menos esto). Lo vamos a probar directamente, primero de todo vamos preparar un proyecto para trabajar con el, empecemos por crearnos un proyecto de ReactJS.</p>\n<p>Para trabajar con react usaremos un paquete de npm que nos instala un proyecto básico inicial, lo instalamos con</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token function\">npm</span> -g <span class=\"token function\">install</span> create-react-app\n</code></pre></div>\n<p>Una vez instalado ya podríamos crearnos un proyecto</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">create-react-app frontWeb\n</code></pre></div>\n<p>Esto nos creará un proyecto de react dentro de una carpeta llamada frontWeb. Para probar si funciona solo tenemos que entrar en la carpeta y ejecutar con:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token function\">npm</span> start\n</code></pre></div>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture.JPG\" alt=\"Capture\"></p>\n<p>Bien ya tenemos nuestra web de react, vamos ahora con la parte del entorno de <em>desarrollo</em> de docker.<br>\nPara ejecutar nuestro entorno de desarrollo en un contenedor solo necesitamos que tenga <strong>node</strong> instalado, es decir, que es similar a lo que hemos creado anteriormente.</p>\n<p>Antes de continuar comentar que aunque vamos a trabajar casi todo el rato con comandos de <strong>docker-compose</strong> todo lo que hagamos a partir de ahora se puede hacer con comandos <strong>docker run</strong> también, pero realmente son comandos muy largos y poco útiles a la larga. En caso de necesidad siempre podemos buscar cual es el flag del comando para ponerlo directamente sin usar un <strong>dockerfile</strong>.</p>\n<p>Continuemos, volvamos al principio, hemos dicho que queríamos un entorno de desarrollo donde nuestro contenedor se actualice automáticamente según vayamos haciendo cambios en local, para ello vamos a hacer uso de lo que en docker se conoce como <em>volumenes</em>.<br>\nLo primero nos crearemos dentro de nuestra carpeta de proyecto de react un fichero <em>dockerfile</em> pero esta vez pondremos:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">Dockerfile.dev\n</code></pre></div>\n<p>Como es normal aunque no lo hayamos visto a docker se le puede indicar el fichero <em>dockerfile</em> a usar cuando hacemos un build, solo tenemos que usar el flag <strong>-f</strong>,  por ejemplo (ojo al punto del final)</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">docker build -f ./Dockerfile.dev <span class=\"token builtin class-name\">.</span>\n</code></pre></div>\n<p>Lo mismo con los ficheros para <strong>docker-compose</strong>, por lo que realmente no tendremos ningún problema y podemos tener varios <em>dockerfile</em> distintos según nuestro entorno.<br>\nSabiendo esto continuamos con nuestro fichero <strong>Dockerfile.dev</strong></p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"docker\"><pre class=\"language-docker\"><code class=\"language-docker\"><span class=\"token instruction\"><span class=\"token keyword\">FROM</span> node:alpine</span>\n\n<span class=\"token instruction\"><span class=\"token keyword\">WORKDIR</span> <span class=\"token string\">'/app'</span></span>\n\n<span class=\"token instruction\"><span class=\"token keyword\">COPY</span> package.json .</span>\n<span class=\"token instruction\"><span class=\"token keyword\">RUN</span> npm install</span>\n\n<span class=\"token instruction\"><span class=\"token keyword\">COPY</span> . .</span>\n\n<span class=\"token instruction\"><span class=\"token keyword\">CMD</span> [<span class=\"token string\">\"npm\"</span>, <span class=\"token string\">\"start\"</span>]</span>\n</code></pre></div>\n<p>Misma teoria que anteriormente, copiamos el package.json primero por posibles cambios solo del resto y no tener que hacer otra vez el <em>npm install</em> todo el rato cada vez que hagamos un build.<br>\nYa tenemos nuestro fichero <em>dockerfile</em>, ahora como la idea es usar <em>docker-compose</em> para todo necesitamos crear el fichero docker-compose.yml</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"yaml\"><pre class=\"language-yaml\"><code class=\"language-yaml\"><span class=\"token key atrule\">version</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'3'</span>\n<span class=\"token key atrule\">services</span><span class=\"token punctuation\">:</span>\n    <span class=\"token key atrule\">web_react</span><span class=\"token punctuation\">:</span>\n        <span class=\"token key atrule\">build</span><span class=\"token punctuation\">:</span> \n            <span class=\"token key atrule\">context</span><span class=\"token punctuation\">:</span> .\n            <span class=\"token key atrule\">dockerfile</span><span class=\"token punctuation\">:</span> Dockerfile.dev\n        <span class=\"token key atrule\">ports</span><span class=\"token punctuation\">:</span>\n            <span class=\"token punctuation\">-</span> <span class=\"token string\">\"3000:3000\"</span>\n</code></pre></div>\n<p>Antes de continuar, vemos que ahora donde tenemos puesto <em>build</em> ahora hemos añadido 2 propiedades:</p>\n<ul>\n<li><strong>context</strong>: Indicamos el contexto desde(path) desde el que trabajara el build del docker-compose.</li>\n<li><strong>dockerfile</strong>: Nombre del fichero dockerfile que queremos usar.</li>\n</ul>\n<p>Continuemos, ahora vamos a hablar del concepto de <strong>Volume</strong> (por fin ;) ), primero añadamoslo al fichero</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"yaml\"><pre class=\"language-yaml\"><code class=\"language-yaml\"><span class=\"token key atrule\">version</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'3'</span>\n<span class=\"token key atrule\">services</span><span class=\"token punctuation\">:</span>\n    <span class=\"token key atrule\">web_react</span><span class=\"token punctuation\">:</span>\n        <span class=\"token key atrule\">build</span><span class=\"token punctuation\">:</span> ./Dockerfile.dev\n        <span class=\"token key atrule\">ports</span><span class=\"token punctuation\">:</span>\n            <span class=\"token punctuation\">-</span> <span class=\"token string\">\"3000:3000\"</span>\n        <span class=\"token key atrule\">volumes</span><span class=\"token punctuation\">:</span>\n            <span class=\"token punctuation\">-</span> /app/node_modules\n            <span class=\"token punctuation\">-</span> .<span class=\"token punctuation\">:</span>/app\n</code></pre></div>\n<p>Si nos fijamos en lo que hemos puesto, tenemos realmente dos conceptos distintos dentro de <em>volumes</em>:</p>\n<ul>\n<li><strong>.:/app</strong>: Hablemos primero del segundo, este es similar al concepto de mapear puertos, básicamente le estamos indicando que <em>mapee</em> todo el contenido de la ruta actual de mi equipo local, al path <em>/app</em> del contenedor, lo que funcionaría similar a un acceso directo a los ficheros de la carpeta local de nuestro equipo.</li>\n<li><strong>/app/node_modules</strong>: Si nos fijamos en esta línea no tenemos <strong>':'</strong>, eso es porque aquí le estamos indicando que haga como un <em>marcador</em> de la carpeta <em>node_modules</em> del contenedor, es decir, usa la del contenedor, no la toques y dejala donde está (esto hace que la carpeta se mantenga aunque hagamos el paso anterior).</li>\n</ul>\n<p>Ahora que ya sabemos lo que hemos puesto, viene la pregunta del ¿por qué?....bien, si pensamos en el proceso que hemos añadido en el <strong>Dockerfile.dev</strong>, tenemos una parte donde instalamos los paquetes que están indicados en el <em>package.json</em>, es decir, queremos que los descargues e instales de nuevo cuando hagamos un build de la imagen del contenedor, y no pasamos la carpeta local <em>node_modules</em> (que es donde instala las dependencias), que de hecho la vamos a eliminar para que veamos como funciona, si, <strong>eliminarla</strong>.</p>\n<p>Ya que hablamos del <strong>Dockerfile.dev</strong>, alguno se puede preguntar si hacemos la refencia o linkado de nuestra carpeta local, ¿para qué hacemos el COPY?....bueno, esto es para prevenir creaciones para producción usando los mismos Dockerfiles, realmente en nuestro caso actual no lo necesitamos pero para producción siempre es mejor para evitar errores, ya que un contenedor en producción <strong>NO DEBE</strong> hacer referencias a carpetas locales de <strong>ningún sitio</strong> solo tiene que tener sus propios ficheros.</p>\n<p>Ya tenemos todo ahora nos situamos en la ruta donde tenemos el fichero <em>docker-compose.yml</em> y ejecutamos:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">docker-compose up\n</code></pre></div>\n<p>Si todo va bien deberíamos ver algo como esto en la consola<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Captura-de-pantalla-2018-11-14-a-las-9.35.40.png\" alt=\"Captura-de-pantalla-2018-11-14-a-las-9.35.40\"></p>\n<p>Y si accedemos en el navegador a:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">localhost:3000\n</code></pre></div>\n<p>Deberíamos ver</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Captura-de-pantalla-2018-11-14-a-las-9.37.02.png\" alt=\"Captura-de-pantalla-2018-11-14-a-las-9.37.02\"></p>\n<p>Bien como tal ya tenemos todo funcionando, pero realmente lo que queremos es poder desarrollar en local y que se actualice el contenedor , ¿no?... pues vamos a probarlo.<br>\nNos vamos a nuestra web de react, y dentro de la carpeta <em>src</em> modificamos el fichero <em>App.js</em> y ponemos lo que queramos:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\"> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&#x3C;</span>div</span> <span class=\"token attr-name\">className</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>App<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&#x3C;</span>header</span> <span class=\"token attr-name\">className</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>App-header<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&#x3C;</span>img</span> <span class=\"token attr-name\">src</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span>{logo}</span> <span class=\"token attr-name\">className</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>App-logo<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">alt</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>logo<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&#x3C;</span>p</span><span class=\"token punctuation\">></span></span>\n            Hola ninjaaaaasssss\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&#x3C;/</span>p</span><span class=\"token punctuation\">></span></span> //<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&#x3C;</span>--</span> <span class=\"token attr-name\">Esta</span> <span class=\"token attr-name\">es</span> <span class=\"token attr-name\">la</span> <span class=\"token attr-name\">linea</span> <span class=\"token attr-name\">que</span> <span class=\"token attr-name\">cambiamos</span>\n          <span class=\"token attr-name\">&#x3C;a</span>\n            <span class=\"token attr-name\">className</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>App-link<span class=\"token punctuation\">\"</span></span>\n            <span class=\"token attr-name\">href</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>https://reactjs.org<span class=\"token punctuation\">\"</span></span>\n            <span class=\"token attr-name\">target</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>_blank<span class=\"token punctuation\">\"</span></span>\n            <span class=\"token attr-name\">rel</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>noopener noreferrer<span class=\"token punctuation\">\"</span></span>\n          <span class=\"token punctuation\">></span></span>\n            Learn React\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&#x3C;/</span>a</span><span class=\"token punctuation\">></span></span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&#x3C;/</span>header</span><span class=\"token punctuation\">></span></span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&#x3C;/</span>div</span><span class=\"token punctuation\">></span></span>\n</code></pre></div>\n<p>Y una vez que guardemos el documento automáticamente se debería actualizar el navegador y mostrar</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Captura-de-pantalla-2018-11-14-a-las-9.40.32.png\" alt=\"Captura-de-pantalla-2018-11-14-a-las-9.40.32\"></p>\n<p>¡¡¡PERFECTO!!!... ya tenemos nuestro entorno de desarrollo funcionando.</p>\n<p>Empecemos con el entorno de <strong>TEST</strong></p>\n<h4 id=\"test\">TEST</h4>\n<p>Por defecto react viene ya configurado con 1 test para poder probar, solo tenemos que hacer</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token function\">npm</span> run <span class=\"token builtin class-name\">test</span>\n</code></pre></div>\n<p>o</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token function\">npm</span> <span class=\"token builtin class-name\">test</span>\n</code></pre></div>\n<p>y automáticamente nos pasaría los tests</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-1.JPG\" alt=\"Capture-1\"></p>\n<p>Bien, pues ahora queremos esto pero en un contenedor, como opción rápida podemos ejecutar una imagen creada con el mismo <em>dockerfile</em> pero cambiando el comando de arranque (esto es solo para que veais que funciona).</p>\n<p>Por si no la tenemos creamos el build de la imagen, yo la voy a <em>taggear</em> para poder identificarla</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">docker build -f ./Dockerfile.dev <span class=\"token builtin class-name\">.</span> -t test_react\n</code></pre></div>\n<p>Esto nos devuelve una imagen con ese nombre</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-2.JPG\" alt=\"Capture-2\"></p>\n<p>Ya la tenemos, ahora solo vamos a realizar un <em>run</em> habitual cambiando el comando de arranque</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">docker run -it test_react <span class=\"token function\">npm</span> <span class=\"token builtin class-name\">test</span>\n</code></pre></div>\n<p>Le he añadido <em>-it</em> para poder trabajar con la consola de test y como algo nuevo si nos fijamos hemos puesto <em>cosas</em> tras el nombre de la imagen, básicamente todo lo que ponemos a continuación del nombre de la imagen a ejecutar lo toma como comando de arranque para el contenedor. Si lo ejecutamos nos devuelve<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-3.JPG\" alt=\"Capture-3\"></p>\n<p>Otra opción es añadirlo a nuestro <em>docker-compose</em> añadiendo otro servicio pero con la misma teoría, compartiendo o <em>mapeando</em> ficheros entre el equipo local y el contenedor, teniendo 2 contenedores funcionando uno para las pruebas en desarrollo y otro probando los test. El problema de este acercamiento es que no tenemos control sobre la consola de test por lo que no podemos hacer mucho más que ver como pasan los tests cada vez que hacemos un cambio en los ficheros.<br>\nVamos a probarlo, cambiamos nuestro fichero <em>docker-compose</em></p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"yaml\"><pre class=\"language-yaml\"><code class=\"language-yaml\"><span class=\"token key atrule\">version</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'3'</span>\n<span class=\"token key atrule\">services</span><span class=\"token punctuation\">:</span>\n    <span class=\"token key atrule\">web_react</span><span class=\"token punctuation\">:</span>\n        <span class=\"token key atrule\">build</span><span class=\"token punctuation\">:</span>\n            <span class=\"token key atrule\">context</span><span class=\"token punctuation\">:</span> .\n            <span class=\"token key atrule\">dockerfile</span><span class=\"token punctuation\">:</span> Dockerfile.dev\n        <span class=\"token key atrule\">ports</span><span class=\"token punctuation\">:</span>\n            <span class=\"token punctuation\">-</span> <span class=\"token string\">\"3000:3000\"</span>\n        <span class=\"token key atrule\">volumes</span><span class=\"token punctuation\">:</span>\n            <span class=\"token punctuation\">-</span> /app/node_modules\n            <span class=\"token punctuation\">-</span> .<span class=\"token punctuation\">:</span>/app\n    <span class=\"token key atrule\">test_react</span><span class=\"token punctuation\">:</span>\n        <span class=\"token key atrule\">build</span><span class=\"token punctuation\">:</span>\n            <span class=\"token key atrule\">context</span><span class=\"token punctuation\">:</span> .\n            <span class=\"token key atrule\">dockerfile</span><span class=\"token punctuation\">:</span> Dockerfile.dev\n        <span class=\"token key atrule\">volumes</span><span class=\"token punctuation\">:</span>\n            <span class=\"token punctuation\">-</span> /app/node_modules\n            <span class=\"token punctuation\">-</span> .<span class=\"token punctuation\">:</span>/app\n        <span class=\"token key atrule\">command</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"npm\"</span><span class=\"token punctuation\">,</span><span class=\"token string\">\"test\"</span><span class=\"token punctuation\">]</span>\n</code></pre></div>\n<p>Como véis hemos añadido otro servicio (contenedor ya sabéis), en este caso se llama <strong>test_react</strong>, que usa el mismo <em>dockerfile</em> y mapea de la misma forma los <em>volumenes</em>. Despues de eso si que tiene cambios, hemos quitado el <em>mapeo</em> del puerto porque ya no lo necesitamos y como extra nuevo hemos añadido la propiedad <strong>command</strong> que básicamente lo que hace es cambiar el comando de inicio del contenedor.<br>\nA continuación si ejecutamos nuestro <em>docker-compose up</em>, nos crea dos contenedores y como podremos ver el log ambos funcionan correctamente, y si cambiamos algo en los ficheros se actualizan ambos, tanto el de desarrollo como el que pasa los tests.</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-4.JPG\" alt=\"Capture-4\"></p>\n<p>Ninguno de los casos es muy <strong>ideal</strong> pero son funcionales y puede que en algún caso nos pueda servir para algo, más adelante veremos un entorno de test más 'real' por el momento esto es más que suficiente, a continuación empezaremos a hablar un poco de <strong>PRODUCCIÓN</strong></p>\n<h4 id=\"produccin\">PRODUCCIÓN</h4>\n<p>Pasemos ahora a <em>producción</em>, la intención es crear un contenedor que nos devuelva nuestra aplicación ya preparada para producción, para el que no lo sepa, una app de react la preparamos para producción ejecutando el comando:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token function\">npm</span> run build\n</code></pre></div>\n<p>Y este comando nos deja unos ficheros típicos de web (html, js y css), es decir, <em>ficheros estáticos</em>. Estos ficheros los deja en una carpeta llamada <strong>build</strong> dentro de nuestro proyecto.</p>\n<p>Ahora necesitamos para producción un <em>servidor web</em>, los más utilizados son <strong>Apache o Nginx</strong>, aunque podríamos hacerlo con NodeJS, Go, Ruby, etc..... con casi todos los lenguajes tenemos alguna opción para hacerlo. En nuestro caso usaremos un contenedor con Nginx.</p>\n<p>Si miramos la documentación del <a href=\"https://hub.docker.com/_/nginx/\">contenedor oficial</a> podemos ver que los ficheros los sirve desde el path <strong>/usr/share/nginx/html</strong>. Sabiendo esto entonces básicamente lo que tendriamos que hacer sería copiar nuestros ficheros de producción en esa ruta del contenedor de nginx... pero claro se supone que no tenemos en local los archivos, veamos como podemos hacerlo con el entorno que tenemos ahora.</p>\n<p>Nos vamos a crear un nuevo <strong>dockerfile</strong> con esto</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"docker\"><pre class=\"language-docker\"><code class=\"language-docker\"><span class=\"token instruction\"><span class=\"token keyword\">FROM</span> node:alpine <span class=\"token keyword\">as</span> builder</span>\n<span class=\"token instruction\"><span class=\"token keyword\">WORKDIR</span> <span class=\"token string\">'/app'</span></span>\n<span class=\"token instruction\"><span class=\"token keyword\">COPY</span> package.json .</span>\n<span class=\"token instruction\"><span class=\"token keyword\">RUN</span> npm install</span>\n<span class=\"token instruction\"><span class=\"token keyword\">COPY</span> . .</span>\n<span class=\"token instruction\"><span class=\"token keyword\">RUN</span> npm run build</span>\n\n<span class=\"token instruction\"><span class=\"token keyword\">FROM</span> nginx</span>\n<span class=\"token instruction\"><span class=\"token keyword\">COPY</span> <span class=\"token options\"><span class=\"token property\">--from</span><span class=\"token punctuation\">=</span><span class=\"token string\">builder</span></span> /app/build /usr/share/nginx/html</span>\n</code></pre></div>\n<p>Empecemos por la primera linea:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">FROM node:alpine as builder\n</code></pre></div>\n<p>Introducimos algo nuevo en este punto, básicamente lo que estamos haciendo es indicarle al proceso que añada como una referencia al resultado del <em>build</em> de ese contenedor con nombre <em>builder</em>, pero puede ser cualquier otro. Esta referencia solo está disponible en el contexto de la ejecución de <em>docker build</em>.<br>\nEl resto del primer contenedor es algo que ya hemos visto, vayamos con el segundo</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"docker\"><pre class=\"language-docker\"><code class=\"language-docker\"><span class=\"token instruction\"><span class=\"token keyword\">FROM</span> nginx</span>\n<span class=\"token instruction\"><span class=\"token keyword\">COPY</span> <span class=\"token options\"><span class=\"token property\">--from</span><span class=\"token punctuation\">=</span><span class=\"token string\">builder</span></span> /app/build /usr/share/nginx/html</span>\n</code></pre></div>\n<p>Aquí empezamos con el segundo contenedor. Vemos como la instrucción COPY tiene algo nuevo</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"docker\"><pre class=\"language-docker\"><code class=\"language-docker\">--from=builder\n</code></pre></div>\n<p>Como os podéis imaginar tiene que ver con la instrucción <em>as builder</em> del primer contenedor, aquí le estamos diciendo que del primer contenedor se copie la ruta <em>/app/build</em> y la pegue en <em>/usr/share/nginx/html</em><br>\nBien pues vamos a ejecutar nuestro nuevo build</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">docker build <span class=\"token builtin class-name\">.</span>\n</code></pre></div>\n<p>Una vez terminado</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-5.JPG\" alt=\"Capture-5\"></p>\n<p>Tenemos ya construido una imagen con supuestamente <strong>nginx</strong> y nuestra app en producción. Por último nos faltaría crear un contenedor con esa imagen, pues vamos a ello</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">docker run -p <span class=\"token number\">3500</span>:80 --name webpro idImagen\n</code></pre></div>\n<p>Como extra he añadido <strong>--name</strong> que lo que hace es <em>taggearnos</em> el contenedor con un nombre que podamos gestionar de manera más comoda que un ID numérico</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-6.JPG\" alt=\"Capture-6\"></p>\n<p>Se puede ver al principio el comando y a continuación un log (el de nginx) una vez que intentamos acceder a la página</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture2.JPG\" alt=\"Capture2\"></p>\n<p>Y como podemos ver ya tenemos nuestro entorno para producción que básicamente es el build del <em>dockerfile</em> una vez que hemos terminado de desarrollar.</p>\n<p>En próximos posts veremos una forma más profesional de hacer todo esto con <em>Integración Continua</em> gracias a <strong>TravisCI</strong> y <strong>GitHub</strong>.</p>\n<!--kg-card-end: markdown-->","htmlAst":{"type":"root","children":[{"type":"comment","value":"kg-card-begin: markdown"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"La idea es ir empezando a ver como sería un entorno real de desarrollo con Docker teniendo:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Nuestro entorno de desarrollo"}]},{"type":"text","value":": Un entorno donde "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"creamos"}]}]},{"type":"text","value":" las cosas."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Entorno de test"}]},{"type":"text","value":": Tras el desarrollo, pasamos nuestro código al entorno de test donde, como su propio nombre indica, probamos que todo funciona."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Entorno de producción"}]},{"type":"text","value":": Tras pasar los tests pertinentes automáticamente el proyecto pasaría a producción."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Este "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"workflow"}]},{"type":"text","value":" es lo que comunmente se conoce como "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Integración Continua, Continuous Integration o CI"}]},{"type":"text","value":". Para este proceso usaremos herramientas o servicios como Github o Travis CI y desarrollaremos con ReactJS (no importa que no sepamos usarlos veremos lo necesario para entender lo que estamos haciendo)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"entornodedesarrollo"},"children":[{"type":"text","value":"Entorno de desarrollo"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Empecemos por el primero de los entornos, el entorno de desarrollo. Lo que buscamos en este entorno es que nuestros cambios mientras estamos desarrollando se "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"sincronicen"}]},{"type":"text","value":" automáticamente con el contenedor de desarrollo  (esto en varios casos es innecesario pero lo veremos igualmente con los fines didácticos que nos ocupan)."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nPensando en el objetivo de este entorno, ya hemos visto que si realizamos cambios en nuestro código tenemos que volver a realizar un "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"build"}]}]},{"type":"text","value":" y luego arrancar un contenedor nuevo con la imagen que nos crearía el build anterior. Esto realmente no es lo que estamos buscando, es poco eficiente y tendríamos demasiadas imágenes de contenedor."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En docker existe una forma de solucionar esto, vamos a introducir algo que no hemos visto todavia: "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Los Volúmenes"}]},{"type":"text","value":"."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nEn docker un "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"volumen"}]},{"type":"text","value":" no deja de ser una referencia al filesystem del contenedor y puede ser una referencia, como un "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"mapeo"}]},{"type":"text","value":" (al igual que los puertos) de una carpeta local a una del contenedor, o un 'no lo toques' (que básicamente es mapea todo menos esto). Lo vamos a probar directamente, primero de todo vamos preparar un proyecto para trabajar con el, empecemos por crearnos un proyecto de ReactJS."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Para trabajar con react usaremos un paquete de npm que nos instala un proyecto básico inicial, lo instalamos con"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"shell"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" -g "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"install"}]},{"type":"text","value":" create-react-app\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Una vez instalado ya podríamos crearnos un proyecto"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"create-react-app frontWeb\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Esto nos creará un proyecto de react dentro de una carpeta llamada frontWeb. Para probar si funciona solo tenemos que entrar en la carpeta y ejecutar con:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"shell"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" start\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture.JPG","alt":"Capture"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bien ya tenemos nuestra web de react, vamos ahora con la parte del entorno de "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"desarrollo"}]},{"type":"text","value":" de docker."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nPara ejecutar nuestro entorno de desarrollo en un contenedor solo necesitamos que tenga "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"node"}]},{"type":"text","value":" instalado, es decir, que es similar a lo que hemos creado anteriormente."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Antes de continuar comentar que aunque vamos a trabajar casi todo el rato con comandos de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"docker-compose"}]},{"type":"text","value":" todo lo que hagamos a partir de ahora se puede hacer con comandos "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"docker run"}]},{"type":"text","value":" también, pero realmente son comandos muy largos y poco útiles a la larga. En caso de necesidad siempre podemos buscar cual es el flag del comando para ponerlo directamente sin usar un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"dockerfile"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Continuemos, volvamos al principio, hemos dicho que queríamos un entorno de desarrollo donde nuestro contenedor se actualice automáticamente según vayamos haciendo cambios en local, para ello vamos a hacer uso de lo que en docker se conoce como "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"volumenes"}]},{"type":"text","value":"."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nLo primero nos crearemos dentro de nuestra carpeta de proyecto de react un fichero "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"dockerfile"}]},{"type":"text","value":" pero esta vez pondremos:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"shell"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-shell"]},"children":[{"type":"text","value":"Dockerfile.dev\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como es normal aunque no lo hayamos visto a docker se le puede indicar el fichero "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"dockerfile"}]},{"type":"text","value":" a usar cuando hacemos un build, solo tenemos que usar el flag "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"-f"}]},{"type":"text","value":",  por ejemplo (ojo al punto del final)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"shell"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-shell"]},"children":[{"type":"text","value":"docker build -f ./Dockerfile.dev "},{"type":"element","tagName":"span","properties":{"className":["token","builtin","class-name"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Lo mismo con los ficheros para "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"docker-compose"}]},{"type":"text","value":", por lo que realmente no tendremos ningún problema y podemos tener varios "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"dockerfile"}]},{"type":"text","value":" distintos según nuestro entorno."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nSabiendo esto continuamos con nuestro fichero "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Dockerfile.dev"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"docker"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-docker"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-docker"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"FROM"}]},{"type":"text","value":" node:alpine"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"WORKDIR"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/app'"}]}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"COPY"}]},{"type":"text","value":" package.json ."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"RUN"}]},{"type":"text","value":" npm install"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"COPY"}]},{"type":"text","value":" . ."}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"CMD"}]},{"type":"text","value":" ["},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"npm\""}]},{"type":"text","value":", "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"start\""}]},{"type":"text","value":"]"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Misma teoria que anteriormente, copiamos el package.json primero por posibles cambios solo del resto y no tener que hacer otra vez el "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"npm install"}]},{"type":"text","value":" todo el rato cada vez que hagamos un build."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nYa tenemos nuestro fichero "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"dockerfile"}]},{"type":"text","value":", ahora como la idea es usar "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"docker-compose"}]},{"type":"text","value":" para todo necesitamos crear el fichero docker-compose.yml"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"yaml"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-yaml"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-yaml"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"version"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'3'"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"services"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"web_react"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"build"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" \n            "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"context"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" .\n            "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"dockerfile"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" Dockerfile.dev\n        "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"ports"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"3000:3000\""}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Antes de continuar, vemos que ahora donde tenemos puesto "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"build"}]},{"type":"text","value":" ahora hemos añadido 2 propiedades:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"context"}]},{"type":"text","value":": Indicamos el contexto desde(path) desde el que trabajara el build del docker-compose."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"dockerfile"}]},{"type":"text","value":": Nombre del fichero dockerfile que queremos usar."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Continuemos, ahora vamos a hablar del concepto de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Volume"}]},{"type":"text","value":" (por fin ;) ), primero añadamoslo al fichero"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"yaml"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-yaml"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-yaml"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"version"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'3'"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"services"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"web_react"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"build"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" ./Dockerfile.dev\n        "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"ports"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"3000:3000\""}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"volumes"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" /app/node_modules\n            "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" ."},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"/app\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Si nos fijamos en lo que hemos puesto, tenemos realmente dos conceptos distintos dentro de "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"volumes"}]},{"type":"text","value":":"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":".:/app"}]},{"type":"text","value":": Hablemos primero del segundo, este es similar al concepto de mapear puertos, básicamente le estamos indicando que "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"mapee"}]},{"type":"text","value":" todo el contenido de la ruta actual de mi equipo local, al path "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"/app"}]},{"type":"text","value":" del contenedor, lo que funcionaría similar a un acceso directo a los ficheros de la carpeta local de nuestro equipo."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"/app/node_modules"}]},{"type":"text","value":": Si nos fijamos en esta línea no tenemos "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"':'"}]},{"type":"text","value":", eso es porque aquí le estamos indicando que haga como un "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"marcador"}]},{"type":"text","value":" de la carpeta "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"node_modules"}]},{"type":"text","value":" del contenedor, es decir, usa la del contenedor, no la toques y dejala donde está (esto hace que la carpeta se mantenga aunque hagamos el paso anterior)."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Ahora que ya sabemos lo que hemos puesto, viene la pregunta del ¿por qué?....bien, si pensamos en el proceso que hemos añadido en el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Dockerfile.dev"}]},{"type":"text","value":", tenemos una parte donde instalamos los paquetes que están indicados en el "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"package.json"}]},{"type":"text","value":", es decir, queremos que los descargues e instales de nuevo cuando hagamos un build de la imagen del contenedor, y no pasamos la carpeta local "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"node_modules"}]},{"type":"text","value":" (que es donde instala las dependencias), que de hecho la vamos a eliminar para que veamos como funciona, si, "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"eliminarla"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Ya que hablamos del "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Dockerfile.dev"}]},{"type":"text","value":", alguno se puede preguntar si hacemos la refencia o linkado de nuestra carpeta local, ¿para qué hacemos el COPY?....bueno, esto es para prevenir creaciones para producción usando los mismos Dockerfiles, realmente en nuestro caso actual no lo necesitamos pero para producción siempre es mejor para evitar errores, ya que un contenedor en producción "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"NO DEBE"}]},{"type":"text","value":" hacer referencias a carpetas locales de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"ningún sitio"}]},{"type":"text","value":" solo tiene que tener sus propios ficheros."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Ya tenemos todo ahora nos situamos en la ruta donde tenemos el fichero "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"docker-compose.yml"}]},{"type":"text","value":" y ejecutamos:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"shell"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-shell"]},"children":[{"type":"text","value":"docker-compose up\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Si todo va bien deberíamos ver algo como esto en la consola"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Captura-de-pantalla-2018-11-14-a-las-9.35.40.png","alt":"Captura-de-pantalla-2018-11-14-a-las-9.35.40"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y si accedemos en el navegador a:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"shell"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-shell"]},"children":[{"type":"text","value":"localhost:3000\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Deberíamos ver"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Captura-de-pantalla-2018-11-14-a-las-9.37.02.png","alt":"Captura-de-pantalla-2018-11-14-a-las-9.37.02"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bien como tal ya tenemos todo funcionando, pero realmente lo que queremos es poder desarrollar en local y que se actualice el contenedor , ¿no?... pues vamos a probarlo."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nNos vamos a nuestra web de react, y dentro de la carpeta "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"src"}]},{"type":"text","value":" modificamos el fichero "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"App.js"}]},{"type":"text","value":" y ponemos lo que queramos:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"html"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-html"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-html"]},"children":[{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"className"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"App"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"header"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"className"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"App-header"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"img"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"src"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":"{logo}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"className"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"App-logo"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"alt"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"logo"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"/>"}]}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"p"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"text","value":"\n            Hola ninjaaaaasssss\n          "},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"</"}]},{"type":"text","value":"p"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"text","value":" //"},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"--"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"Esta"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"es"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"la"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"linea"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"que"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"cambiamos"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"<a"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"className"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"App-link"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"href"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"https://reactjs.org"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"target"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"_blank"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"rel"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"noopener noreferrer"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"text","value":"\n            Learn React\n          "},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"</"}]},{"type":"text","value":"a"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"</"}]},{"type":"text","value":"header"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"</"}]},{"type":"text","value":"div"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y una vez que guardemos el documento automáticamente se debería actualizar el navegador y mostrar"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Captura-de-pantalla-2018-11-14-a-las-9.40.32.png","alt":"Captura-de-pantalla-2018-11-14-a-las-9.40.32"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"¡¡¡PERFECTO!!!... ya tenemos nuestro entorno de desarrollo funcionando."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Empecemos con el entorno de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"TEST"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h4","properties":{"id":"test"},"children":[{"type":"text","value":"TEST"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Por defecto react viene ya configurado con 1 test para poder probar, solo tenemos que hacer"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"shell"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" run "},{"type":"element","tagName":"span","properties":{"className":["token","builtin","class-name"]},"children":[{"type":"text","value":"test"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"o"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"shell"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","builtin","class-name"]},"children":[{"type":"text","value":"test"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"y automáticamente nos pasaría los tests"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-1.JPG","alt":"Capture-1"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bien, pues ahora queremos esto pero en un contenedor, como opción rápida podemos ejecutar una imagen creada con el mismo "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"dockerfile"}]},{"type":"text","value":" pero cambiando el comando de arranque (esto es solo para que veais que funciona)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Por si no la tenemos creamos el build de la imagen, yo la voy a "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"taggear"}]},{"type":"text","value":" para poder identificarla"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"shell"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-shell"]},"children":[{"type":"text","value":"docker build -f ./Dockerfile.dev "},{"type":"element","tagName":"span","properties":{"className":["token","builtin","class-name"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":" -t test_react\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Esto nos devuelve una imagen con ese nombre"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-2.JPG","alt":"Capture-2"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Ya la tenemos, ahora solo vamos a realizar un "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"run"}]},{"type":"text","value":" habitual cambiando el comando de arranque"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"shell"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-shell"]},"children":[{"type":"text","value":"docker run -it test_react "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","builtin","class-name"]},"children":[{"type":"text","value":"test"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Le he añadido "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"-it"}]},{"type":"text","value":" para poder trabajar con la consola de test y como algo nuevo si nos fijamos hemos puesto "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"cosas"}]},{"type":"text","value":" tras el nombre de la imagen, básicamente todo lo que ponemos a continuación del nombre de la imagen a ejecutar lo toma como comando de arranque para el contenedor. Si lo ejecutamos nos devuelve"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-3.JPG","alt":"Capture-3"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Otra opción es añadirlo a nuestro "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"docker-compose"}]},{"type":"text","value":" añadiendo otro servicio pero con la misma teoría, compartiendo o "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"mapeando"}]},{"type":"text","value":" ficheros entre el equipo local y el contenedor, teniendo 2 contenedores funcionando uno para las pruebas en desarrollo y otro probando los test. El problema de este acercamiento es que no tenemos control sobre la consola de test por lo que no podemos hacer mucho más que ver como pasan los tests cada vez que hacemos un cambio en los ficheros."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nVamos a probarlo, cambiamos nuestro fichero "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"docker-compose"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"yaml"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-yaml"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-yaml"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"version"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'3'"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"services"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"web_react"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"build"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"context"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" .\n            "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"dockerfile"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" Dockerfile.dev\n        "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"ports"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"3000:3000\""}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"volumes"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" /app/node_modules\n            "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" ."},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"/app\n    "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"test_react"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"build"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"context"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" .\n            "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"dockerfile"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" Dockerfile.dev\n        "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"volumes"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" /app/node_modules\n            "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" ."},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"/app\n        "},{"type":"element","tagName":"span","properties":{"className":["token","key","atrule"]},"children":[{"type":"text","value":"command"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"npm\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"test\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como véis hemos añadido otro servicio (contenedor ya sabéis), en este caso se llama "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"test_react"}]},{"type":"text","value":", que usa el mismo "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"dockerfile"}]},{"type":"text","value":" y mapea de la misma forma los "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"volumenes"}]},{"type":"text","value":". Despues de eso si que tiene cambios, hemos quitado el "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"mapeo"}]},{"type":"text","value":" del puerto porque ya no lo necesitamos y como extra nuevo hemos añadido la propiedad "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"command"}]},{"type":"text","value":" que básicamente lo que hace es cambiar el comando de inicio del contenedor."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nA continuación si ejecutamos nuestro "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"docker-compose up"}]},{"type":"text","value":", nos crea dos contenedores y como podremos ver el log ambos funcionan correctamente, y si cambiamos algo en los ficheros se actualizan ambos, tanto el de desarrollo como el que pasa los tests."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-4.JPG","alt":"Capture-4"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Ninguno de los casos es muy "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"ideal"}]},{"type":"text","value":" pero son funcionales y puede que en algún caso nos pueda servir para algo, más adelante veremos un entorno de test más 'real' por el momento esto es más que suficiente, a continuación empezaremos a hablar un poco de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"PRODUCCIÓN"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h4","properties":{"id":"produccin"},"children":[{"type":"text","value":"PRODUCCIÓN"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Pasemos ahora a "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"producción"}]},{"type":"text","value":", la intención es crear un contenedor que nos devuelva nuestra aplicación ya preparada para producción, para el que no lo sepa, una app de react la preparamos para producción ejecutando el comando:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"shell"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" run build\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y este comando nos deja unos ficheros típicos de web (html, js y css), es decir, "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"ficheros estáticos"}]},{"type":"text","value":". Estos ficheros los deja en una carpeta llamada "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"build"}]},{"type":"text","value":" dentro de nuestro proyecto."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Ahora necesitamos para producción un "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"servidor web"}]},{"type":"text","value":", los más utilizados son "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Apache o Nginx"}]},{"type":"text","value":", aunque podríamos hacerlo con NodeJS, Go, Ruby, etc..... con casi todos los lenguajes tenemos alguna opción para hacerlo. En nuestro caso usaremos un contenedor con Nginx."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Si miramos la documentación del "},{"type":"element","tagName":"a","properties":{"href":"https://hub.docker.com/_/nginx/"},"children":[{"type":"text","value":"contenedor oficial"}]},{"type":"text","value":" podemos ver que los ficheros los sirve desde el path "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"/usr/share/nginx/html"}]},{"type":"text","value":". Sabiendo esto entonces básicamente lo que tendriamos que hacer sería copiar nuestros ficheros de producción en esa ruta del contenedor de nginx... pero claro se supone que no tenemos en local los archivos, veamos como podemos hacerlo con el entorno que tenemos ahora."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Nos vamos a crear un nuevo "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"dockerfile"}]},{"type":"text","value":" con esto"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"docker"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-docker"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-docker"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"FROM"}]},{"type":"text","value":" node:alpine "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"as"}]},{"type":"text","value":" builder"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"WORKDIR"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/app'"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"COPY"}]},{"type":"text","value":" package.json ."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"RUN"}]},{"type":"text","value":" npm install"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"COPY"}]},{"type":"text","value":" . ."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"RUN"}]},{"type":"text","value":" npm run build"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"FROM"}]},{"type":"text","value":" nginx"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"COPY"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","options"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","property"]},"children":[{"type":"text","value":"--from"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"builder"}]}]},{"type":"text","value":" /app/build /usr/share/nginx/html"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Empecemos por la primera linea:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"FROM node:alpine as builder\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Introducimos algo nuevo en este punto, básicamente lo que estamos haciendo es indicarle al proceso que añada como una referencia al resultado del "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"build"}]},{"type":"text","value":" de ese contenedor con nombre "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"builder"}]},{"type":"text","value":", pero puede ser cualquier otro. Esta referencia solo está disponible en el contexto de la ejecución de "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"docker build"}]},{"type":"text","value":"."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nEl resto del primer contenedor es algo que ya hemos visto, vayamos con el segundo"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"docker"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-docker"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-docker"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"FROM"}]},{"type":"text","value":" nginx"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","instruction"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"COPY"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","options"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","property"]},"children":[{"type":"text","value":"--from"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"builder"}]}]},{"type":"text","value":" /app/build /usr/share/nginx/html"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Aquí empezamos con el segundo contenedor. Vemos como la instrucción COPY tiene algo nuevo"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"docker"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-docker"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-docker"]},"children":[{"type":"text","value":"--from=builder\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como os podéis imaginar tiene que ver con la instrucción "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"as builder"}]},{"type":"text","value":" del primer contenedor, aquí le estamos diciendo que del primer contenedor se copie la ruta "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"/app/build"}]},{"type":"text","value":" y la pegue en "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"/usr/share/nginx/html"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nBien pues vamos a ejecutar nuestro nuevo build"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"shell"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-shell"]},"children":[{"type":"text","value":"docker build "},{"type":"element","tagName":"span","properties":{"className":["token","builtin","class-name"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Una vez terminado"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-5.JPG","alt":"Capture-5"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Tenemos ya construido una imagen con supuestamente "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"nginx"}]},{"type":"text","value":" y nuestra app en producción. Por último nos faltaría crear un contenedor con esa imagen, pues vamos a ello"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"shell"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-shell"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-shell"]},"children":[{"type":"text","value":"docker run -p "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"3500"}]},{"type":"text","value":":80 --name webpro idImagen\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como extra he añadido "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"--name"}]},{"type":"text","value":" que lo que hace es "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"taggearnos"}]},{"type":"text","value":" el contenedor con un nombre que podamos gestionar de manera más comoda que un ID numérico"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture-6.JPG","alt":"Capture-6"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Se puede ver al principio el comando y a continuación un log (el de nginx) una vez que intentamos acceder a la página"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2018/11/Capture2.JPG","alt":"Capture2"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y como podemos ver ya tenemos nuestro entorno para producción que básicamente es el build del "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"dockerfile"}]},{"type":"text","value":" una vez que hemos terminado de desarrollar."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En próximos posts veremos una forma más profesional de hacer todo esto con "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Integración Continua"}]},{"type":"text","value":" gracias a "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"TravisCI"}]},{"type":"text","value":" y "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"GitHub"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"comment","value":"kg-card-end: markdown"}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"entornodedesarrollo","heading":"Entorno de desarrollo","items":[{"id":"test","heading":"TEST"},{"id":"produccin","heading":"PRODUCCIÓN"}]}]},"featureImageSharp":{"base":"docker_facebook_share-3.png","publicURL":"/static/8250fb6cd246dd294ed3fc4d99218f71/docker_facebook_share-3.png","imageMeta":{"width":336,"height":287},"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsTAAALEwEAmpwYAAADmElEQVQ4y21Ua0wUVxQ+s8PMvbvgo0YlaWP8UZvYGK2JsU39Y2IwNcZWiI+aqt2YIGjLuhRdtYDFBXlUBbQtLnQXV80uuCi0FNvaovFBUdEpxl9qamtTAR8FY+sfKbC3350dwFU3+XJ2zr3nO995zBA989M3N5GeczyGvJ9t+vYfbOo7LmKlBjHvL2Q/LshxQpDuCsfhuZ90sqKLpGdHSN9UH8PWFjOBluEfB7IqtuO00x58RLy6R+EV1214JlZwllj+KdIkcdZTxLr7KPEv/iAtvTr2vOXbMSCcpXu+m6Z/ciyVlXUKVnihOfGsoIlCEK+8QbZFUL7zfIL6roe09TWoqnGUkBWcI1bcQXr+KY1520j3NL/FdnUIVnJlkJUYT1jZrwIqg9zXTfqnJ19in52pSFhe4AAhqam5LyAEGdt1ycZ2thEue1lh+1VWfHnQJCw1BlgpCIsudiFZPdQv4ftvCfhCLK91hZYVcsjK4giRVdE+Oow+hKayogtdrOyqVPcfLzWGoA7oHDRJAQyrin95+z7Khuo2wzbfyW0pGYTWjBLyypsqr7ghSy/nB+4Iu6/7SWJ1dzTBdzfKfN1RHsMQ93X185p7Ancf6+7IQlJ1xRxIdkSJL7nEUHlhOybWuhaBQqn9t598vdG0pj+jkw/9HdX8fVF7oG/AHvxngFf9JXBvG1pEUzAgbIQi1cWXnN2gUJqX6L3cJEdJx63XAr+L5S09Q3MiD4aYvzdqr30o7IFegU0QWJWqpHZBSW1C0V11ilwvuToj+2guJ9bmdW+z+kpuIyW7gzMqf7pm9DzoE+XGQzG+Gor2/dbPyzov69u/f98R6jfj5CC0TH/8YmtYRgk41bE5ESKnn1burpdHygRPw1z34dNLZxe3LCZnzRQyBMmVsh98ZNM+PqJiulAYllAtKwlDcssVaeGYCDuPNh4hWuWjWd5vaNlXP9KkrceIbQq/reU0JWuZteZbZMbFYkYAYcqoIyu8CLYcSJeksE76MEAOd10Kc4VXIOnn8E3H2Zuwk4FVwKvAG0CmPMPK0TDzGtgNQBZw0rqwGvABeVbQXuASgtJg9wMBoA5olSIg6GXzXY7JDq2HU5KmAg1IsBZWKm7AmQc2Gff2WiRS2ddAEMgH9lgVSnHKcC9kUzPgXGe14IOYWrNHS6DKhSQpKFsDFlilbgRmArPhS9SGP2PPftfMFoz8Dz3VcDm8+CFYqqyY2Nn/8hrXL6If80cAAAAASUVORK5CYII=","aspectRatio":1.174496644295302,"src":"/static/8250fb6cd246dd294ed3fc4d99218f71/5742b/docker_facebook_share-3.png","srcSet":"/static/8250fb6cd246dd294ed3fc4d99218f71/847ef/docker_facebook_share-3.png 175w,\n/static/8250fb6cd246dd294ed3fc4d99218f71/5742b/docker_facebook_share-3.png 336w","srcWebp":"/static/8250fb6cd246dd294ed3fc4d99218f71/8cfb4/docker_facebook_share-3.webp","srcSetWebp":"/static/8250fb6cd246dd294ed3fc4d99218f71/9fca7/docker_facebook_share-3.webp 175w,\n/static/8250fb6cd246dd294ed3fc4d99218f71/8cfb4/docker_facebook_share-3.webp 336w","sizes":"(max-width: 336px) 100vw, 336px"}}}},"allGhostPost":{"edges":[{"node":{"id":"Ghost__Post__5fd65ddfa6c0f5058bff49a1","title":"JS Algoritmos y  Estructuras de datos VII: La recursividad  III - Resolviendo problemas II","slug":"js-algoritmos-y-estructuras-de-datos-vii-la-recursividad-iii","featured":false,"feature_image":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/unordered-3192273_640-1.png","excerpt":"Bien en el post anterior vimos la primera de las opciones para compensar el\nproblema del maximum call stack que nos podía dar la recursividad. En este post\nveremos algunas otras opciones para tener en nuestro arsenal, que cumplen (más o\nmenos) con la resolución de nuestro problema aunque alguna sea bastante lenta y\ntengan el handicap de que debemos controlar la asincronía.\n\nUsando setTimeout\nEn este caso vamos a jugar con el conocido setTimeout, en este punto es mejor\nque estemos familiarizados ","custom_excerpt":null,"visibility":"public","created_at_pretty":"13 Dec 2020","published_at_pretty":"28 Dec 2020","updated_at_pretty":"19 Jan 2021","created_at":"2020-12-13T19:30:55.000+01:00","published_at":"2020-12-28T10:30:00.000+01:00","updated_at":"2021-01-19T21:13:02.000+01:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"Perfil.jpg","publicURL":"/static/b0de6281fb28a266510b3b09b9243e5a/Perfil.jpg","imageMeta":{"width":307,"height":307},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUDBAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGzw6zC6zHn+cLYP//EAB0QAAICAQUAAAAAAAAAAAAAAAEDAAIEEyEiIzL/2gAIAQEAAQUCifca8KgcKWVfUpkHsG5pxX//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAdEAACAgEFAAAAAAAAAAAAAAAAARARcQISIUFR/9oACAEBAAY/AhU88xkb7N06a8P/xAAcEAEAAwEAAwEAAAAAAAAAAAABABEhMUFRYXH/2gAIAQEAAT8hR2pq40aqb+xIAeXibhW9JXr8joF4TBcSNe0//9oADAMBAAIAAwAAABDzDwD/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAcEAEAAgIDAQAAAAAAAAAAAAABABEhUTFhcfD/2gAIAQEAAT8QyItrELaTlatLwU63MvEW6vUNdy4LZQDn7iVApV9VLtANdWwKkuYq4Er1VZ//2Q==","aspectRatio":1,"src":"/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg","srcSet":"/static/b0de6281fb28a266510b3b09b9243e5a/f340b/Perfil.jpg 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/22d64/Perfil.jpg 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/aa249/Perfil.jpg 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/0dc33/Perfil.jpg 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/60667/Perfil.jpg 307w","srcWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp","srcSetWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/59cda/Perfil.webp 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/7da75/Perfil.webp 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f282e/Perfil.webp 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/a7b21/Perfil.webp 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f59af/Perfil.webp 307w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"algoritmos","url":"https://jlgarcia.fulldev.ninja/tag/algoritmos/","name":"algoritmos","visibility":"public","feature_image":null,"description":null,"meta_title":null,"meta_description":null,"featureImageSharp":null},"tags":[{"slug":"algoritmos","url":"https://jlgarcia.fulldev.ninja/tag/algoritmos/","name":"algoritmos","visibility":"public","feature_image":null,"description":null,"meta_title":null,"meta_description":null,"featureImageSharp":null},{"slug":"javascript","url":"https://jlgarcia.fulldev.ninja/tag/javascript/","name":"javascript","visibility":"public","feature_image":null,"description":null,"meta_title":null,"meta_description":null,"featureImageSharp":null}],"plaintext":"Bien en el post anterior vimos la primera de las opciones para compensar el\nproblema del maximum call stack que nos podía dar la recursividad. En este post\nveremos algunas otras opciones para tener en nuestro arsenal, que cumplen (más o\nmenos) con la resolución de nuestro problema aunque alguna sea bastante lenta y\ntengan el handicap de que debemos controlar la asincronía.\n\nUsando setTimeout\nEn este caso vamos a jugar con el conocido setTimeout, en este punto es mejor\nque estemos familiarizados con el event-loop (recomiendo leer estos posts\n[https://blog.insiderattack.net/event-loop-and-the-big-picture-nodejs-event-loop-part-1-1cb67a182810]\n)\n\nUsaremos este ejemplo, cambia un poco lo que teniamos antes, pero es por\nintentar seguir con el mismo concepto del sumatorio\n\nlet accum = 0\nlet number = 5\n\nfunction addTo () {\n\tif (number === 0) { \n\t\tconsole.log(accum)\n\t\treturn\n\t}\n\t\n\tsetTimeout(() => {\n\t\taccum = number + accum\n\t\tnumber--\n\t\taddTo()\n\t}, 0)\n}\n\n\nfunction finish () {\n  console.log('Finished')\n}\n\naddTo()\nfinish()\n\n\nComo vemos tenemos nuestra función addTo que si el número no es 0 pasa por un \nsetTimeout con 0. Esto aunque no podamos verlo en la aplicación que lo incluye\ndentro de la task queue lo que hace es incluir el método en la timers queue y se\nejecutaría según el ciclo de vida habitual de node cuando pase por los timers \nresueltos.\n\nVeamos un poco lo que pasa cuando ejecutamos esto dentro de jv9000 (OJO que esto\nno funciona en la web tengo un fork modificado para permitir esto y otras cosas)\n\n 1. Incluye en el call stack la primera ejecución de addTo\n    \n    \n    \n 2. Como number no es 0 se ejecuta el setTimeout, es decir, incluye la función\n    anónima dentro de la timers queue, que para nosotros en nuestro visualizador\n    esta dentro de la task queue\n    \n    \n    \n 3. Importante, el paso anterior ha pasado como a un segundo plano dentro del\n    event loop, por lo que para nosotros ha terminado la ejecución de addTo por\n    lo que ya la podemos sacar del call stack\n    \n    \n    \n 4. El loop continua y le toca a la función finish.\n    \n    Importante en este punto darse cuenta de que ha entrado la función finish al \n    call stack se ha ejecutado y ha salido, sin que todavía hayamos tocado lo\n    que tenemos dentro de task queue\n    \n    \n 5. Una vez ejecutada la función finish ya le toca el turno a comprobar task, al\n    ver que tenemos algo lo pasa al call stack y lo ejecuta\n    \n    \n    \n 6. Al ejecutarlo dentro del call stack, lo que tenemos de nuevo es otra\n    ejecución de addTo, que repite la operación incluye en la task queue la\n    función anónima del timeout\n    \n    \n    \n\nY el proceso se repite n veces hasta que se cumple el number === 0\n\n\nDonde terminaría nuestra ejecución. Como vemos aquí tenemos otro caso donde\nevitamos que la cola de llamadas se llene.\n\nUsando setImmediate\nUsando setImmediate es similar al setTimeout pero tiene menos pasos, en el caso\nanterior nuestra ejecución pasa por incluirse en la cola de task, comprobar el\ntiempo, ver que ha terminado incluirlo en el call stack y ejecutarlo. Al final\nson bastantes pasos. Sin embargo el setImmediate tiene su propia cola y se\nejecutan al momento tras los eventos de I/O por lo que puede ser más rápido en\nun entorno recursivo. Veamos rápidamente la diferencia:\n\nlet accum = 0\nlet number = 5\n\nfunction addTo () {\n\tif (number === 0) { \n\t\tconsole.log(accum)\n\t\treturn\n\t}\n\t\n\tsetImmediate(() => {\n\t\taccum = number + accum\n\t\tnumber--\n\t\taddTo()\n\t})\n}\n\n\nfunction finish () {\n  console.log('Finished')\n}\n\naddTo()\nfinish()\n\n\n 1. Al igual que antes se ejecuta la primera vez addTo\n    \n 2. Al igual que antes pasa al finish, pero fijemonos que no tenemos en la cola\n    de task, es decir, no estamos pendientes de que realmente termine nada.\n    \n 3. De repente, si continuaramos ejecutando vemos como ha desaparecido todo y de\n    repente aparece un método anónimo en nuestro call stack, que no es otro que\n    la ejecución de lo que tenemos dentro del setImmediate\n    \n 4. Y al igual que antes, este ejecutaría de nuevo nuestra función addTo\n    \n\nEste proceso se repetiría, veriamos como entra anonymous, luego addTo, termina \naddTo y desaparece, termina anonymous y desaparece, y en el siguiente ciclo todo\nse repite, hasta que coincide con number===0 que hace que se termine\n\n\nComo vemos es bastante similar al proceso con setTimeout pero con menos pasos,\nesto no quiere decir que tenga que ser siempre más rápido, a fin de cuentas,\nambos pasan por el event loop casi de la misma forma.\n\nUsando process.nextTick\nPor último veremos como será nuestra solución usando process.nextTick(). En este\ncaso todo es igual que con setImmediate:\n\nlet accum = 0\nlet number = 5\n\nfunction addTo () {\n\tif (number === 0) { \n\t\tconsole.log(accum)\n\t\treturn\n\t}\n\t\n\tprocess.nextTick(() => {\n\t\taccum = number + accum\n\t\tnumber--\n\t\taddTo()\n\t})\n}\n\n\nfunction finish () {\n  console.log('Finished')\n}\n\naddTo()\nfinish()\n\n\nEn este ejemplo me ahorraré las imágenes ya que visualmente sigue el mismo\nproceso que setImmediate:\n\n 1. Se ejecuta la primera vez addTo\n 2. A continuación finish\n 3. Anonymous (lo que está dentro de nextTick)\n 4. addTo....\n 5. y el proceso se repite\n\nUsando process.nextTick, tenemos otra solución pero en este caso, el beneficio\nes la velocidad, si echamos un vistazo a como se procesan las colas:\n\n\nPodremos ver como nextTick se ejecuta tras cada hito dentro del loop, lo que\nsignifica que no tenemos que repetir el ciclo de vida del loop para volver a\nencontrarnos con el nextTick, como ocurre con los timers o el setImmediate.\n\nCon esto de la recursión realmente lo que quería era mostrar un poco como\nsolucionar problemas de maximum call stack y que se viera un poco que ocurre por\ndentro del event loop que no está de más tenerlo a veces en cuenta cuando\ntenemos ciertos problemas.\n\nEn siguientes posts de esta serie empezaremos con los algoritmos de búsqueda.\nOtro tema bastante interesante creo yo. Sin más, nos vemos en el siguiente un\nabrazoooooo","html":"<!--kg-card-begin: markdown--><p>Bien en el post anterior vimos la primera de las opciones para compensar el problema del <em>maximum call stack</em> que nos podía dar la recursividad. En este post veremos algunas otras opciones para tener en nuestro arsenal, que cumplen (más o menos) con la resolución de nuestro problema aunque alguna sea bastante lenta y tengan el handicap de que debemos controlar la asincronía.</p>\n<h3 id=\"usandosettimeout\">Usando setTimeout</h3>\n<p>En este caso vamos a jugar con el conocido <strong>setTimeout</strong>, en este punto es mejor que estemos familiarizados con el <strong>event-loop</strong> (<a href=\"https://blog.insiderattack.net/event-loop-and-the-big-picture-nodejs-event-loop-part-1-1cb67a182810\">recomiendo leer estos posts</a>)</p>\n<p>Usaremos este ejemplo, cambia un poco lo que teniamos antes, pero es por intentar seguir con el mismo concepto del sumatorio</p>\n<pre><code class=\"language-javascript\">let accum = 0\nlet number = 5\n\nfunction addTo () {\n\tif (number === 0) { \n\t\tconsole.log(accum)\n\t\treturn\n\t}\n\t\n\tsetTimeout(() =&gt; {\n\t\taccum = number + accum\n\t\tnumber--\n\t\taddTo()\n\t}, 0)\n}\n\n\nfunction finish () {\n  console.log('Finished')\n}\n\naddTo()\nfinish()\n</code></pre>\n<p>Como vemos tenemos nuestra función <strong>addTo</strong> que si el número no es 0 pasa por un <strong>setTimeout</strong> con 0. Esto aunque no podamos verlo en la aplicación que lo incluye dentro de la <strong>task queue</strong> lo que hace es incluir el método en la <strong>timers queue</strong> y se ejecutaría según el ciclo de vida habitual de node cuando pase por los <strong>timers</strong> resueltos.</p>\n<p>Veamos un poco lo que pasa cuando ejecutamos esto dentro de <strong>jv9000</strong> <strong>(OJO que esto no funciona en la web tengo un fork modificado para permitir esto y otras cosas)</strong></p>\n<ol>\n<li>\n<p>Incluye en el call stack la primera ejecución de <strong>addTo</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.24.06.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-20.24.06\"></p>\n</li>\n<li>\n<p>Como <em>number</em> no es 0 se ejecuta el <em>setTimeout</em>, es decir, incluye la función anónima dentro de la <em>timers queue</em>, que para nosotros en nuestro visualizador esta dentro de la <em>task queue</em><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.24.21.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-20.24.21\"></p>\n</li>\n<li>\n<p>Importante, el paso anterior ha pasado como a un segundo plano dentro del event loop, por lo que para nosotros ha terminado la ejecución de <strong>addTo</strong> por lo que ya la podemos sacar del <strong>call stack</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.24.36.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-20.24.36\"></p>\n</li>\n<li>\n<p>El loop continua y le toca a la función finish.<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.25.02.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-20.25.02\"><br>\nImportante en este punto darse cuenta de que ha entrado la función finish al <em>call stack</em> se ha ejecutado y ha salido, sin que todavía hayamos tocado lo que tenemos dentro de <em>task queue</em></p>\n</li>\n<li>\n<p>Una vez ejecutada la función <em>finish</em> ya le toca el turno a comprobar <em>task</em>, al ver que tenemos algo lo pasa al <em>call stack</em> y lo ejecuta<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.25.43.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-20.25.43\"></p>\n</li>\n<li>\n<p>Al ejecutarlo dentro del call stack, lo que tenemos de nuevo es otra ejecución de <em>addTo</em>, que repite la operación incluye en la <em>task queue</em> la función anónima del timeout<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.37.26.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-20.37.26\"></p>\n</li>\n</ol>\n<p>Y el proceso se repite <strong>n</strong> veces hasta que se cumple el <strong>number === 0</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.55.37.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-20.55.37\"></p>\n<p>Donde terminaría nuestra ejecución. Como vemos aquí tenemos otro caso donde evitamos que la cola de llamadas se llene.</p>\n<h3 id=\"usandosetimmediate\">Usando setImmediate</h3>\n<p>Usando <strong>setImmediate</strong> es similar al setTimeout pero tiene menos pasos, en el caso anterior nuestra ejecución pasa por incluirse en la cola de task, comprobar el tiempo, ver que ha terminado incluirlo en el call stack y ejecutarlo. Al final son bastantes pasos. Sin embargo el <strong>setImmediate</strong> tiene su propia cola y se ejecutan al momento tras los eventos de I/O por lo que puede ser más rápido en un entorno recursivo. Veamos rápidamente la diferencia:</p>\n<pre><code class=\"language-javascript\">let accum = 0\nlet number = 5\n\nfunction addTo () {\n\tif (number === 0) { \n\t\tconsole.log(accum)\n\t\treturn\n\t}\n\t\n\tsetImmediate(() =&gt; {\n\t\taccum = number + accum\n\t\tnumber--\n\t\taddTo()\n\t})\n}\n\n\nfunction finish () {\n  console.log('Finished')\n}\n\naddTo()\nfinish()\n</code></pre>\n<ol>\n<li>Al igual que antes se ejecuta la primera vez <strong>addTo</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.09.51.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-21.09.51\"></li>\n<li>Al igual que antes pasa al finish, pero fijemonos que no tenemos en la cola de <em>task</em>, es decir, no estamos pendientes de que realmente termine nada.<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.10.03.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-21.10.03\"></li>\n<li>De repente, si continuaramos ejecutando vemos como ha desaparecido todo y de repente aparece un método anónimo en nuestro call stack, que no es otro que la ejecución de lo que tenemos dentro del <em>setImmediate</em><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.10.23.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-21.10.23\"></li>\n<li>Y al igual que antes, este ejecutaría de nuevo nuestra función <em>addTo</em><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.10.32.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-21.10.32\"></li>\n</ol>\n<p>Este proceso se repetiría, veriamos como entra <em>anonymous</em>, luego <em>addTo</em>, termina <em>addTo</em> y desaparece, termina <em>anonymous</em> y desaparece, y en el siguiente ciclo todo se repite, hasta que coincide con <strong>number===0</strong> que hace que se termine<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.13.54.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-21.13.54\"></p>\n<p>Como vemos es bastante similar al proceso con <em>setTimeout</em> pero con menos pasos, esto no quiere decir que tenga que ser siempre más rápido, a fin de cuentas, ambos pasan por el event loop casi de la misma forma.</p>\n<h3 id=\"usandoprocessnexttick\">Usando process.nextTick</h3>\n<p>Por último veremos como será nuestra solución usando <strong>process.nextTick()</strong>. En este caso todo es igual que con setImmediate:</p>\n<pre><code class=\"language-javascript\">let accum = 0\nlet number = 5\n\nfunction addTo () {\n\tif (number === 0) { \n\t\tconsole.log(accum)\n\t\treturn\n\t}\n\t\n\tprocess.nextTick(() =&gt; {\n\t\taccum = number + accum\n\t\tnumber--\n\t\taddTo()\n\t})\n}\n\n\nfunction finish () {\n  console.log('Finished')\n}\n\naddTo()\nfinish()\n</code></pre>\n<p>En este ejemplo me ahorraré las imágenes ya que visualmente sigue el mismo proceso que setImmediate:</p>\n<ol>\n<li>Se ejecuta la primera vez <strong>addTo</strong></li>\n<li>A continuación finish</li>\n<li>Anonymous (lo que está dentro de nextTick)</li>\n<li><strong>addTo</strong>....</li>\n<li>y el proceso se repite</li>\n</ol>\n<p>Usando <strong>process.nextTick</strong>, tenemos otra solución pero en este caso, el beneficio es la velocidad, si echamos un vistazo a como se procesan las colas:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.26.21.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-21.26.21\"></p>\n<p>Podremos ver como nextTick se ejecuta tras cada <em>hito</em> dentro del loop, lo que significa que no tenemos que repetir el ciclo de vida del loop para volver a encontrarnos con el <em>nextTick</em>, como ocurre con los timers o el <em>setImmediate</em>.</p>\n<p>Con esto de la recursión realmente lo que quería era mostrar un poco como solucionar problemas de <em>maximum call stack</em> y que se viera un poco que ocurre por dentro del event loop que no está de más tenerlo a veces en cuenta cuando tenemos ciertos problemas.</p>\n<p>En siguientes posts de esta serie empezaremos con los algoritmos de búsqueda. Otro tema bastante interesante creo yo. Sin más, nos vemos en el siguiente un abrazoooooo</p>\n<!--kg-card-end: markdown-->","url":"https://jlgarcia.fulldev.ninja/js-algoritmos-y-estructuras-de-datos-vii-la-recursividad-iii/","canonical_url":null,"uuid":"84196055-084f-4e7d-83aa-f721d0ea1a51","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"5fd65ddfa6c0f5058bff49a1","reading_time":5,"send_email_when_published":false,"email_subject":null,"childHtmlRehype":{"html":"<!--kg-card-begin: markdown--><p>Bien en el post anterior vimos la primera de las opciones para compensar el problema del <em>maximum call stack</em> que nos podía dar la recursividad. En este post veremos algunas otras opciones para tener en nuestro arsenal, que cumplen (más o menos) con la resolución de nuestro problema aunque alguna sea bastante lenta y tengan el handicap de que debemos controlar la asincronía.</p>\n<h3 id=\"usandosettimeout\">Usando setTimeout</h3>\n<p>En este caso vamos a jugar con el conocido <strong>setTimeout</strong>, en este punto es mejor que estemos familiarizados con el <strong>event-loop</strong> (<a href=\"https://blog.insiderattack.net/event-loop-and-the-big-picture-nodejs-event-loop-part-1-1cb67a182810\">recomiendo leer estos posts</a>)</p>\n<p>Usaremos este ejemplo, cambia un poco lo que teniamos antes, pero es por intentar seguir con el mismo concepto del sumatorio</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">let</span> accum <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n<span class=\"token keyword\">let</span> number <span class=\"token operator\">=</span> <span class=\"token number\">5</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">addTo</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>number <span class=\"token operator\">===</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> \n\t\tconsole<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>accum<span class=\"token punctuation\">)</span>\n\t\t<span class=\"token keyword\">return</span>\n\t<span class=\"token punctuation\">}</span>\n\t\n\t<span class=\"token function\">setTimeout</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n\t\taccum <span class=\"token operator\">=</span> number <span class=\"token operator\">+</span> accum\n\t\tnumber<span class=\"token operator\">--</span>\n\t\t<span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\t<span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">finish</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Finished'</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token function\">finish</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n</code></pre></div>\n<p>Como vemos tenemos nuestra función <strong>addTo</strong> que si el número no es 0 pasa por un <strong>setTimeout</strong> con 0. Esto aunque no podamos verlo en la aplicación que lo incluye dentro de la <strong>task queue</strong> lo que hace es incluir el método en la <strong>timers queue</strong> y se ejecutaría según el ciclo de vida habitual de node cuando pase por los <strong>timers</strong> resueltos.</p>\n<p>Veamos un poco lo que pasa cuando ejecutamos esto dentro de <strong>jv9000</strong> <strong>(OJO que esto no funciona en la web tengo un fork modificado para permitir esto y otras cosas)</strong></p>\n<ol>\n<li>\n<p>Incluye en el call stack la primera ejecución de <strong>addTo</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.24.06.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-20.24.06\"></p>\n</li>\n<li>\n<p>Como <em>number</em> no es 0 se ejecuta el <em>setTimeout</em>, es decir, incluye la función anónima dentro de la <em>timers queue</em>, que para nosotros en nuestro visualizador esta dentro de la <em>task queue</em><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.24.21.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-20.24.21\"></p>\n</li>\n<li>\n<p>Importante, el paso anterior ha pasado como a un segundo plano dentro del event loop, por lo que para nosotros ha terminado la ejecución de <strong>addTo</strong> por lo que ya la podemos sacar del <strong>call stack</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.24.36.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-20.24.36\"></p>\n</li>\n<li>\n<p>El loop continua y le toca a la función finish.<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.25.02.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-20.25.02\"><br>\nImportante en este punto darse cuenta de que ha entrado la función finish al <em>call stack</em> se ha ejecutado y ha salido, sin que todavía hayamos tocado lo que tenemos dentro de <em>task queue</em></p>\n</li>\n<li>\n<p>Una vez ejecutada la función <em>finish</em> ya le toca el turno a comprobar <em>task</em>, al ver que tenemos algo lo pasa al <em>call stack</em> y lo ejecuta<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.25.43.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-20.25.43\"></p>\n</li>\n<li>\n<p>Al ejecutarlo dentro del call stack, lo que tenemos de nuevo es otra ejecución de <em>addTo</em>, que repite la operación incluye en la <em>task queue</em> la función anónima del timeout<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.37.26.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-20.37.26\"></p>\n</li>\n</ol>\n<p>Y el proceso se repite <strong>n</strong> veces hasta que se cumple el <strong>number === 0</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.55.37.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-20.55.37\"></p>\n<p>Donde terminaría nuestra ejecución. Como vemos aquí tenemos otro caso donde evitamos que la cola de llamadas se llene.</p>\n<h3 id=\"usandosetimmediate\">Usando setImmediate</h3>\n<p>Usando <strong>setImmediate</strong> es similar al setTimeout pero tiene menos pasos, en el caso anterior nuestra ejecución pasa por incluirse en la cola de task, comprobar el tiempo, ver que ha terminado incluirlo en el call stack y ejecutarlo. Al final son bastantes pasos. Sin embargo el <strong>setImmediate</strong> tiene su propia cola y se ejecutan al momento tras los eventos de I/O por lo que puede ser más rápido en un entorno recursivo. Veamos rápidamente la diferencia:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">let</span> accum <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n<span class=\"token keyword\">let</span> number <span class=\"token operator\">=</span> <span class=\"token number\">5</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">addTo</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>number <span class=\"token operator\">===</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> \n\t\tconsole<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>accum<span class=\"token punctuation\">)</span>\n\t\t<span class=\"token keyword\">return</span>\n\t<span class=\"token punctuation\">}</span>\n\t\n\t<span class=\"token function\">setImmediate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n\t\taccum <span class=\"token operator\">=</span> number <span class=\"token operator\">+</span> accum\n\t\tnumber<span class=\"token operator\">--</span>\n\t\t<span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\t<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">finish</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Finished'</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token function\">finish</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n</code></pre></div>\n<ol>\n<li>Al igual que antes se ejecuta la primera vez <strong>addTo</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.09.51.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-21.09.51\"></li>\n<li>Al igual que antes pasa al finish, pero fijemonos que no tenemos en la cola de <em>task</em>, es decir, no estamos pendientes de que realmente termine nada.<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.10.03.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-21.10.03\"></li>\n<li>De repente, si continuaramos ejecutando vemos como ha desaparecido todo y de repente aparece un método anónimo en nuestro call stack, que no es otro que la ejecución de lo que tenemos dentro del <em>setImmediate</em><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.10.23.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-21.10.23\"></li>\n<li>Y al igual que antes, este ejecutaría de nuevo nuestra función <em>addTo</em><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.10.32.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-21.10.32\"></li>\n</ol>\n<p>Este proceso se repetiría, veriamos como entra <em>anonymous</em>, luego <em>addTo</em>, termina <em>addTo</em> y desaparece, termina <em>anonymous</em> y desaparece, y en el siguiente ciclo todo se repite, hasta que coincide con <strong>number===0</strong> que hace que se termine<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.13.54.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-21.13.54\"></p>\n<p>Como vemos es bastante similar al proceso con <em>setTimeout</em> pero con menos pasos, esto no quiere decir que tenga que ser siempre más rápido, a fin de cuentas, ambos pasan por el event loop casi de la misma forma.</p>\n<h3 id=\"usandoprocessnexttick\">Usando process.nextTick</h3>\n<p>Por último veremos como será nuestra solución usando <strong>process.nextTick()</strong>. En este caso todo es igual que con setImmediate:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">let</span> accum <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n<span class=\"token keyword\">let</span> number <span class=\"token operator\">=</span> <span class=\"token number\">5</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">addTo</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>number <span class=\"token operator\">===</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> \n\t\tconsole<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>accum<span class=\"token punctuation\">)</span>\n\t\t<span class=\"token keyword\">return</span>\n\t<span class=\"token punctuation\">}</span>\n\t\n\tprocess<span class=\"token punctuation\">.</span><span class=\"token function\">nextTick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n\t\taccum <span class=\"token operator\">=</span> number <span class=\"token operator\">+</span> accum\n\t\tnumber<span class=\"token operator\">--</span>\n\t\t<span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\t<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">finish</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Finished'</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token function\">finish</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n</code></pre></div>\n<p>En este ejemplo me ahorraré las imágenes ya que visualmente sigue el mismo proceso que setImmediate:</p>\n<ol>\n<li>Se ejecuta la primera vez <strong>addTo</strong></li>\n<li>A continuación finish</li>\n<li>Anonymous (lo que está dentro de nextTick)</li>\n<li><strong>addTo</strong>....</li>\n<li>y el proceso se repite</li>\n</ol>\n<p>Usando <strong>process.nextTick</strong>, tenemos otra solución pero en este caso, el beneficio es la velocidad, si echamos un vistazo a como se procesan las colas:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.26.21.png\" alt=\"Captura-de-pantalla-2020-12-21-a-las-21.26.21\"></p>\n<p>Podremos ver como nextTick se ejecuta tras cada <em>hito</em> dentro del loop, lo que significa que no tenemos que repetir el ciclo de vida del loop para volver a encontrarnos con el <em>nextTick</em>, como ocurre con los timers o el <em>setImmediate</em>.</p>\n<p>Con esto de la recursión realmente lo que quería era mostrar un poco como solucionar problemas de <em>maximum call stack</em> y que se viera un poco que ocurre por dentro del event loop que no está de más tenerlo a veces en cuenta cuando tenemos ciertos problemas.</p>\n<p>En siguientes posts de esta serie empezaremos con los algoritmos de búsqueda. Otro tema bastante interesante creo yo. Sin más, nos vemos en el siguiente un abrazoooooo</p>\n<!--kg-card-end: markdown-->","htmlAst":{"type":"root","children":[{"type":"comment","value":"kg-card-begin: markdown"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bien en el post anterior vimos la primera de las opciones para compensar el problema del "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"maximum call stack"}]},{"type":"text","value":" que nos podía dar la recursividad. En este post veremos algunas otras opciones para tener en nuestro arsenal, que cumplen (más o menos) con la resolución de nuestro problema aunque alguna sea bastante lenta y tengan el handicap de que debemos controlar la asincronía."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"usandosettimeout"},"children":[{"type":"text","value":"Usando setTimeout"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En este caso vamos a jugar con el conocido "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"setTimeout"}]},{"type":"text","value":", en este punto es mejor que estemos familiarizados con el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"event-loop"}]},{"type":"text","value":" ("},{"type":"element","tagName":"a","properties":{"href":"https://blog.insiderattack.net/event-loop-and-the-big-picture-nodejs-event-loop-part-1-1cb67a182810"},"children":[{"type":"text","value":"recomiendo leer estos posts"}]},{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Usaremos este ejemplo, cambia un poco lo que teniamos antes, pero es por intentar seguir con el mismo concepto del sumatorio"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" accum "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"5"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" \n\t\tconsole"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"accum"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\t\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\t\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setTimeout"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t\taccum "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"+"}]},{"type":"text","value":" accum\n\t\tnumber"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"--"}]},{"type":"text","value":"\n\t\t"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"finish"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Finished'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"finish"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como vemos tenemos nuestra función "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"addTo"}]},{"type":"text","value":" que si el número no es 0 pasa por un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"setTimeout"}]},{"type":"text","value":" con 0. Esto aunque no podamos verlo en la aplicación que lo incluye dentro de la "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"task queue"}]},{"type":"text","value":" lo que hace es incluir el método en la "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"timers queue"}]},{"type":"text","value":" y se ejecutaría según el ciclo de vida habitual de node cuando pase por los "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"timers"}]},{"type":"text","value":" resueltos."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Veamos un poco lo que pasa cuando ejecutamos esto dentro de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"jv9000"}]},{"type":"text","value":" "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"(OJO que esto no funciona en la web tengo un fork modificado para permitir esto y otras cosas)"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Incluye en el call stack la primera ejecución de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.24.06.png","alt":"Captura-de-pantalla-2020-12-21-a-las-20.24.06"},"children":[]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"number"}]},{"type":"text","value":" no es 0 se ejecuta el "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"setTimeout"}]},{"type":"text","value":", es decir, incluye la función anónima dentro de la "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"timers queue"}]},{"type":"text","value":", que para nosotros en nuestro visualizador esta dentro de la "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"task queue"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.24.21.png","alt":"Captura-de-pantalla-2020-12-21-a-las-20.24.21"},"children":[]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Importante, el paso anterior ha pasado como a un segundo plano dentro del event loop, por lo que para nosotros ha terminado la ejecución de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"addTo"}]},{"type":"text","value":" por lo que ya la podemos sacar del "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"call stack"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.24.36.png","alt":"Captura-de-pantalla-2020-12-21-a-las-20.24.36"},"children":[]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"El loop continua y le toca a la función finish."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.25.02.png","alt":"Captura-de-pantalla-2020-12-21-a-las-20.25.02"},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nImportante en este punto darse cuenta de que ha entrado la función finish al "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"call stack"}]},{"type":"text","value":" se ha ejecutado y ha salido, sin que todavía hayamos tocado lo que tenemos dentro de "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"task queue"}]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Una vez ejecutada la función "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"finish"}]},{"type":"text","value":" ya le toca el turno a comprobar "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"task"}]},{"type":"text","value":", al ver que tenemos algo lo pasa al "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"call stack"}]},{"type":"text","value":" y lo ejecuta"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.25.43.png","alt":"Captura-de-pantalla-2020-12-21-a-las-20.25.43"},"children":[]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Al ejecutarlo dentro del call stack, lo que tenemos de nuevo es otra ejecución de "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"addTo"}]},{"type":"text","value":", que repite la operación incluye en la "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"task queue"}]},{"type":"text","value":" la función anónima del timeout"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.37.26.png","alt":"Captura-de-pantalla-2020-12-21-a-las-20.37.26"},"children":[]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y el proceso se repite "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"n"}]},{"type":"text","value":" veces hasta que se cumple el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"number === 0"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-20.55.37.png","alt":"Captura-de-pantalla-2020-12-21-a-las-20.55.37"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Donde terminaría nuestra ejecución. Como vemos aquí tenemos otro caso donde evitamos que la cola de llamadas se llene."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"usandosetimmediate"},"children":[{"type":"text","value":"Usando setImmediate"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Usando "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"setImmediate"}]},{"type":"text","value":" es similar al setTimeout pero tiene menos pasos, en el caso anterior nuestra ejecución pasa por incluirse en la cola de task, comprobar el tiempo, ver que ha terminado incluirlo en el call stack y ejecutarlo. Al final son bastantes pasos. Sin embargo el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"setImmediate"}]},{"type":"text","value":" tiene su propia cola y se ejecutan al momento tras los eventos de I/O por lo que puede ser más rápido en un entorno recursivo. Veamos rápidamente la diferencia:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" accum "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"5"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" \n\t\tconsole"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"accum"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\t\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\t\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setImmediate"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t\taccum "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"+"}]},{"type":"text","value":" accum\n\t\tnumber"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"--"}]},{"type":"text","value":"\n\t\t"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"finish"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Finished'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"finish"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Al igual que antes se ejecuta la primera vez "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.09.51.png","alt":"Captura-de-pantalla-2020-12-21-a-las-21.09.51"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Al igual que antes pasa al finish, pero fijemonos que no tenemos en la cola de "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"task"}]},{"type":"text","value":", es decir, no estamos pendientes de que realmente termine nada."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.10.03.png","alt":"Captura-de-pantalla-2020-12-21-a-las-21.10.03"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"De repente, si continuaramos ejecutando vemos como ha desaparecido todo y de repente aparece un método anónimo en nuestro call stack, que no es otro que la ejecución de lo que tenemos dentro del "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"setImmediate"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.10.23.png","alt":"Captura-de-pantalla-2020-12-21-a-las-21.10.23"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Y al igual que antes, este ejecutaría de nuevo nuestra función "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.10.32.png","alt":"Captura-de-pantalla-2020-12-21-a-las-21.10.32"},"children":[]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Este proceso se repetiría, veriamos como entra "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"anonymous"}]},{"type":"text","value":", luego "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"addTo"}]},{"type":"text","value":", termina "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"addTo"}]},{"type":"text","value":" y desaparece, termina "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"anonymous"}]},{"type":"text","value":" y desaparece, y en el siguiente ciclo todo se repite, hasta que coincide con "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"number===0"}]},{"type":"text","value":" que hace que se termine"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.13.54.png","alt":"Captura-de-pantalla-2020-12-21-a-las-21.13.54"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como vemos es bastante similar al proceso con "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"setTimeout"}]},{"type":"text","value":" pero con menos pasos, esto no quiere decir que tenga que ser siempre más rápido, a fin de cuentas, ambos pasan por el event loop casi de la misma forma."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"usandoprocessnexttick"},"children":[{"type":"text","value":"Usando process.nextTick"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Por último veremos como será nuestra solución usando "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"process.nextTick()"}]},{"type":"text","value":". En este caso todo es igual que con setImmediate:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" accum "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"5"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" \n\t\tconsole"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"accum"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\t\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\t\n\tprocess"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"nextTick"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t\taccum "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"+"}]},{"type":"text","value":" accum\n\t\tnumber"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"--"}]},{"type":"text","value":"\n\t\t"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"finish"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Finished'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"finish"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En este ejemplo me ahorraré las imágenes ya que visualmente sigue el mismo proceso que setImmediate:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Se ejecuta la primera vez "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"addTo"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"A continuación finish"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Anonymous (lo que está dentro de nextTick)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"addTo"}]},{"type":"text","value":"...."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"y el proceso se repite"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Usando "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"process.nextTick"}]},{"type":"text","value":", tenemos otra solución pero en este caso, el beneficio es la velocidad, si echamos un vistazo a como se procesan las colas:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-21-a-las-21.26.21.png","alt":"Captura-de-pantalla-2020-12-21-a-las-21.26.21"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Podremos ver como nextTick se ejecuta tras cada "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"hito"}]},{"type":"text","value":" dentro del loop, lo que significa que no tenemos que repetir el ciclo de vida del loop para volver a encontrarnos con el "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"nextTick"}]},{"type":"text","value":", como ocurre con los timers o el "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"setImmediate"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Con esto de la recursión realmente lo que quería era mostrar un poco como solucionar problemas de "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"maximum call stack"}]},{"type":"text","value":" y que se viera un poco que ocurre por dentro del event loop que no está de más tenerlo a veces en cuenta cuando tenemos ciertos problemas."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En siguientes posts de esta serie empezaremos con los algoritmos de búsqueda. Otro tema bastante interesante creo yo. Sin más, nos vemos en el siguiente un abrazoooooo"}]},{"type":"text","value":"\n"},{"type":"comment","value":"kg-card-end: markdown"}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"usandosettimeout","heading":"Usando setTimeout"},{"id":"usandosetimmediate","heading":"Usando setImmediate"},{"id":"usandoprocessnexttick","heading":"Usando process.nextTick"}]},"featureImageSharp":{"base":"unordered-3192273_640-1.png","publicURL":"/static/e92df4805fb46ec1f6bec181d2305365/unordered-3192273_640-1.png","imageMeta":{"width":640,"height":512},"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFG0lEQVQ4ywEQBe/6APG/tx3SpZ5Y2+PkQNzf3UjCw89E2M6jZubUibvJxK5Yk5/RHmd0qxNMWpUXsLO/LLe5xT+corsvv7++MmxsaxaZmYUXj4+WHsrKyjrNzc1HANSJfnXTZVT/1X5wp7K+vUSttMg40cSUb+zYh97by4ie0smidOHVpIbbzpWb7Nybsuvbmrbd0ZKAnp/khImK5tyWltuK4uHGPOXl6E3NyMdIAJFqZDnPkIiCwW5inMx1abl/j3YbtLb/AOjCOwXl1IRn2MmFntzNk5Tw46uQ493CYMS+olvt2X+avrSnpo6R6KCEhNulmZrkhs3SsikAABILAMfLzkae0MIY/6TMANl3X5vGi5ajeYjzhYiH66WJi+eaq7TzQuTZqG3v3I+008OFfpKk8ie0pm0n792VubCzwjPOzcE9hofluLOt43/Ue2F8ANfWxzZsXLEeh5X/UKZvjFq/eo3ml6HgedPLukaUk+KxjIvdlPnhcoXu2pwW6tWCl8/Iq1Lp15Cv5NacgElUgxje2r4yvcLqYZeH0tfZdGPhALu70USCg+mpgobwgoyG49zFeobjqqbhhYCO6YmDh+SynZ3VX+bUg4Dq1oeN7NiHxOjXj8jk0XNXfoaCFL29wE7Lx8dK0eznLZB8yaHSgH3MAJuc5qKGhuCF3tmJGo2S6rLIdnrJpYq+sLCIr8LKrbdquMG3RJuZo0vHu4eC6NeQy9HPwUuJjNporKzXYbuzoTe1uLtHuLe0P9BrY8C/fYF/AI+Q58Kur9NhvLfDQ3+K8pXFeW9m3nJZ2d1mRoLUb1ydv8HBKcPc+Cu1qoeG8+med5KY8HOYl+bKjo3nvwBn/w6J0MgV1nhjuayBsuFPctxCAIqK7qybm8txAAAAAXyG8Im3kraj2nBY0M9vZazlcWFlAAAADkseE59cLiD4TiMHc3570auip+BMkJnslKZ3q5PXYkie0GhZ4bR9ntm4na5oAIeJ4GGOj+7S1dDJTqe951G3e5nrx2pZTs2/pT+ZjH9IUSohtkYkGP9XJBf/WCIR/1gwNfV2ds+lv3SH1M97csHfiWiGynJ1za10ncfifGW3AOvajLKkn8qdgYLtx7LA8WbegnGkmn2+vJKn/39iRVHMXjcn/z87N/l/ZFP7OSol/0MsHrvEbG2usHef4ouY+aGJnvF1rn+ozdF3ccLMeGqWAOzZjN7444OryLyvuH2K+8C8iZ/U1IJ2oG+u/zB5ZHl8iHBd/6eWifvKqI3/npGF/ZR5bf/EbW3an7DGK6Sl5YuLiuf/jZb2obahhjO1vMJGAPLflS795oUW9+N/ld/QjMXYyJr43I1t9MdNJzUAOAADpodx58Gfh/+2pJbpw6GH+qSGc9rPblisqpfDcKWj1N7m2KHVo57Myri4vFCtpqwTAP///wA4Qu8NgYTuetbLs6rk1pb/ybOjt9VvZ6nCe3R8vZ6Dvph6YsCjhXPzi3FcsbWUgL/SalawjoTgrpufzW7YypGa3c+i5uvbk3jw34+GANDPuTesrNtxi4zo4oqN87bDubTD5NiUt9zOonzEh23DnoF+8JF8gsfRpHz/jndr07mIdvXMfGaGn6TvrJiW2L23sMDh18qbg8urAAXq2pGqANDQ0EM2NjUTeHidH5qZlSEABVkJ/+eDL9fJh43Hpn/zn4ym/6Ca0f+tnbD+nYaO/7eXhvmxroxy7N6gf8u/p57XzJ513+DcQ7e3uzE9PDMO7sYRFrnPY/gAAAAASUVORK5CYII=","aspectRatio":1.25,"src":"/static/e92df4805fb46ec1f6bec181d2305365/8bef3/unordered-3192273_640-1.png","srcSet":"/static/e92df4805fb46ec1f6bec181d2305365/847ef/unordered-3192273_640-1.png 175w,\n/static/e92df4805fb46ec1f6bec181d2305365/91cba/unordered-3192273_640-1.png 350w,\n/static/e92df4805fb46ec1f6bec181d2305365/8bef3/unordered-3192273_640-1.png 640w","srcWebp":"/static/e92df4805fb46ec1f6bec181d2305365/1ea2e/unordered-3192273_640-1.webp","srcSetWebp":"/static/e92df4805fb46ec1f6bec181d2305365/9fca7/unordered-3192273_640-1.webp 175w,\n/static/e92df4805fb46ec1f6bec181d2305365/37a4e/unordered-3192273_640-1.webp 350w,\n/static/e92df4805fb46ec1f6bec181d2305365/1ea2e/unordered-3192273_640-1.webp 640w","sizes":"(max-width: 640px) 100vw, 640px"}}}}},{"node":{"id":"Ghost__Post__5fbc0b8ba6c0f5058bff47fa","title":"JS Algoritmos y  Estructuras de datos VI: La recursividad  II - Resolviendo problemas  I","slug":"js-algoritmos-y-estructuras-de-datos-vi-la-recursividad-y-como-resolver-el-problema","featured":false,"feature_image":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/unordered-3192273_640.png","excerpt":"Ya vimos en el post anterior cual es el problema principal que podemos tener en\nJavaScript a la hora de usar la recursividad. En un primer momento lo más\nprobable es que nunca nos encontremos con este problema a no ser que trabajemos\ncon una gran cantidad de datos, pero aún así, creo que ver como se soluciona\neste problema puede hacernos entender algunas cosas del funcionamiento de\nJavascript y como podemos usarlas para cualquier otro problema que nos\nencontremos.\n\nPara resolver el problema de \"","custom_excerpt":null,"visibility":"public","created_at_pretty":"23 Nov 2020","published_at_pretty":"21 Dec 2020","updated_at_pretty":"19 Jan 2021","created_at":"2020-11-23T20:20:43.000+01:00","published_at":"2020-12-21T11:00:00.000+01:00","updated_at":"2021-01-19T21:12:09.000+01:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"Perfil.jpg","publicURL":"/static/b0de6281fb28a266510b3b09b9243e5a/Perfil.jpg","imageMeta":{"width":307,"height":307},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUDBAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGzw6zC6zHn+cLYP//EAB0QAAICAQUAAAAAAAAAAAAAAAEDAAIEEyEiIzL/2gAIAQEAAQUCifca8KgcKWVfUpkHsG5pxX//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAdEAACAgEFAAAAAAAAAAAAAAAAARARcQISIUFR/9oACAEBAAY/AhU88xkb7N06a8P/xAAcEAEAAwEAAwEAAAAAAAAAAAABABEhMUFRYXH/2gAIAQEAAT8hR2pq40aqb+xIAeXibhW9JXr8joF4TBcSNe0//9oADAMBAAIAAwAAABDzDwD/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAcEAEAAgIDAQAAAAAAAAAAAAABABEhUTFhcfD/2gAIAQEAAT8QyItrELaTlatLwU63MvEW6vUNdy4LZQDn7iVApV9VLtANdWwKkuYq4Er1VZ//2Q==","aspectRatio":1,"src":"/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg","srcSet":"/static/b0de6281fb28a266510b3b09b9243e5a/f340b/Perfil.jpg 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/22d64/Perfil.jpg 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/aa249/Perfil.jpg 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/0dc33/Perfil.jpg 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/60667/Perfil.jpg 307w","srcWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp","srcSetWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/59cda/Perfil.webp 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/7da75/Perfil.webp 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f282e/Perfil.webp 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/a7b21/Perfil.webp 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f59af/Perfil.webp 307w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"javascript","url":"https://jlgarcia.fulldev.ninja/tag/javascript/","name":"javascript","visibility":"public","feature_image":null,"description":null,"meta_title":null,"meta_description":null,"featureImageSharp":null},"tags":[{"slug":"javascript","url":"https://jlgarcia.fulldev.ninja/tag/javascript/","name":"javascript","visibility":"public","feature_image":null,"description":null,"meta_title":null,"meta_description":null,"featureImageSharp":null},{"slug":"algoritmos","url":"https://jlgarcia.fulldev.ninja/tag/algoritmos/","name":"algoritmos","visibility":"public","feature_image":null,"description":null,"meta_title":null,"meta_description":null,"featureImageSharp":null}],"plaintext":"Ya vimos en el post anterior cual es el problema principal que podemos tener en\nJavaScript a la hora de usar la recursividad. En un primer momento lo más\nprobable es que nunca nos encontremos con este problema a no ser que trabajemos\ncon una gran cantidad de datos, pero aún así, creo que ver como se soluciona\neste problema puede hacernos entender algunas cosas del funcionamiento de\nJavascript y como podemos usarlas para cualquier otro problema que nos\nencontremos.\n\nPara resolver el problema de \"Maximum call stack...\" existen varias formas,\nveremos la mayoría aunque alguna puede que no me guste mucho.\n\nVamos con la primera Trampoline\n\nTrampoline\nEsta se fue extendiendo como una buena posibilidad para resolver el problema,\npero personalmente a mí no me convence demasiado, creo que nos salimos un poco\nde la pureza del concepto de la recursividad pensando en su planteamiento más\nfuncional. Veamos el código en cuestión:\n\nconst trampoline = (fn) => (...args) => {\n  let result = fn(...args)\n  while (typeof result === 'function') {\n    result = result()\n  }\n  return result\n}\n\nfunction addTo(number, accum = 0) {\n\tif (number === 0) {\n\t\treturn accum\n\t}\n\treturn () => addTo(number - 1, number + accum)\n}\n\nfunction finish () {\n  console.log('Finished')\n}\n\nconsole.log(trampoline(addTo)(5))\nfinish()\n\n\nMás de uno se hará una idea de lo que realmente estamos haciendo en este caso y\ncomo cambia con respecto al ejemplo del post anterior sobre recursividad.\nEn este ejemplo tenemos una función addTo que no se llama a si misma, si no que,\nsegún el caso llama a una función anónima que la vuelve a llamar. Pero claro no\npodemos llamar solo a la función addTo ya que en la primera ejecución\nsimplemente devolvería una función que no se ejecuta y terminaría nuestro\nprograma. Lo que hacemos es crear una función trampoline que encapsularía\ncualquier otra donde queramos usar la recursividad. Esta función lo que hace es\ncontrolar si la respuesta es una función que debemos que espera ejecutarse o no,\nen resumen, trampoline es una función que se encarga o de devolver un resultado\nsi se ha cumplido nuestro caso base o de ejecutar de nuevo la función, veamos\nahora lo que pasa en nuestro call stack.\n\n 1. Se ejecuta trampoline\n    \n\nEn cuanto a ejecutar, me refiero a, entre en el call stack y se ejecuta\ndirectamente.\nEsto es una función con currificación, si nos fijamos lo que le pasamos como\nparámetro a trampoline es la función que queremos ejecutar, es decir, addTo.\n\n 2. Se ejecuta trampoline(addTo)(5)\n    \n\nEntra trampoline(addTo)(5) al call stack y comienza a ejecutarse, aquí como\ntenemos un bucle while donde se ejecutan otros métodos, veremos como el call\nstack crece\n\n 3. Se ejecuta por primera vez addTo con el valor 5\n    \n\nComo vemos estamos dentro de trampoline(addTo)(5) ejecutando addTo(5, 0)\nComo el valor no es cero retorna la función anónima que ejecutaria de nuevo \naddTo\n\n\n 4. Se ejecuta la función anónima que a su vez ejecuta addTo(4, 5)\n    \n\nEsto devuelve de nuevo una función anónima, pero como tal su ejecución termina\npor lo que addTo sale del call stack\n\n\nY lo mismo sucede con la función anónima que su ejecución ha terminado y sale\ndel call stack\n\n\n 5. Como el resultado de todo esto sigue siendo una función nuestro trampoline\n    vuelve a ejecutar la función anónima que ha recibido\n    \n\nDonde a su vez se ejecuta addTo(3, 9)\n\n\n 6. Este proceso se repite hasta que el parámetro number === 0 donde termina la\n    ejecución de la función anónima dentro de trampoline\n    \n    \n    \n 7. Se ejecuta el resultado de console.log(trampoline(addTo)(5)) que nos muestra\n    15\n    \n    \n    \n 8. Se ejecuta finish()\n    \n    \n    \n\nEntra dentro del call stack\n\n 9. Ejecuta el console.log dentro de la función finish\n    \n\nY la ejecución de nuestro programa o script termina\n\nComo vemos esto es un truquillo que hace que no saturemos el call stack de\nejecuciones pendientes, que cubre la necesidad que tenemos aunque como digo no\nes algo que me convenza mucho.\n\nEsta es una de las formas que tenemos para evitar el Maximum call stack, en los\nsiguientes post veremos otras posibles soluciones, algunas más sencillas otras\nmás complejas, pero nos serviran para entender del todo como funciona el call\nstack.\n\nNos vemos en el siguiente un abrazoooooo","html":"<!--kg-card-begin: markdown--><p>Ya vimos en el post anterior cual es el problema principal que podemos tener en JavaScript a la hora de usar la recursividad. En un primer momento lo más probable es que nunca nos encontremos con este problema a no ser que trabajemos con una gran cantidad de datos, pero aún así, creo que ver como se soluciona este problema puede hacernos entender algunas cosas del funcionamiento de Javascript y como podemos usarlas para cualquier otro problema que nos encontremos.</p>\n<p>Para resolver el problema de <em>&quot;Maximum call stack...&quot;</em> existen varias formas, veremos la mayoría aunque alguna puede que no me guste mucho.</p>\n<p>Vamos con la primera <strong>Trampoline</strong></p>\n<h3 id=\"trampoline\">Trampoline</h3>\n<p>Esta se fue extendiendo como una buena posibilidad para resolver el problema, pero personalmente a mí no me convence demasiado, creo que nos salimos un poco de la pureza del concepto de la recursividad pensando en su planteamiento más funcional. Veamos el código en cuestión:</p>\n<pre><code class=\"language-javascript\">const trampoline = (fn) =&gt; (...args) =&gt; {\n  let result = fn(...args)\n  while (typeof result === 'function') {\n    result = result()\n  }\n  return result\n}\n\nfunction addTo(number, accum = 0) {\n\tif (number === 0) {\n\t\treturn accum\n\t}\n\treturn () =&gt; addTo(number - 1, number + accum)\n}\n\nfunction finish () {\n  console.log('Finished')\n}\n\nconsole.log(trampoline(addTo)(5))\nfinish()\n</code></pre>\n<p>Más de uno se hará una idea de lo que realmente estamos haciendo en este caso y como cambia con respecto al ejemplo del post anterior sobre recursividad.<br>\nEn este ejemplo tenemos una función <strong>addTo</strong> que no se llama a si misma, si no que, según el caso llama a una función anónima que la vuelve a llamar. Pero claro no podemos llamar solo a la función <strong>addTo</strong> ya que en la primera ejecución simplemente devolvería una función que no se ejecuta y terminaría nuestro programa. Lo que hacemos es crear una función <strong>trampoline</strong> que encapsularía cualquier otra donde queramos usar la recursividad. Esta función lo que hace es controlar si la respuesta es una función que debemos que espera ejecutarse o no, en resumen, trampoline es una función que se encarga o de devolver un resultado si se ha cumplido nuestro <em>caso base</em> o de ejecutar de nuevo la función, veamos ahora lo que pasa en nuestro <em>call stack</em>.</p>\n<ol>\n<li><strong>Se ejecuta <em>trampoline</em></strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.21.36.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.21.36\"></li>\n</ol>\n<p>En cuanto a ejecutar, me refiero a, entre en el call stack y se ejecuta directamente.<br>\nEsto es una función con currificación, si nos fijamos lo que le pasamos como parámetro a <em>trampoline</em> es la función que queremos ejecutar, es decir, <em>addTo</em>.</p>\n<ol start=\"2\">\n<li><strong>Se ejecuta <em>trampoline(addTo)(5)</em></strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.27.10.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.27.10\"></li>\n</ol>\n<p>Entra <strong>trampoline(addTo)(5)</strong> al call stack y comienza a ejecutarse, aquí como tenemos un bucle while donde se ejecutan otros métodos, veremos como el call stack crece</p>\n<ol start=\"3\">\n<li><strong>Se ejecuta por primera vez <em>addTo</em> con el valor 5</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.29.38.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.29.38\"></li>\n</ol>\n<p>Como vemos estamos dentro de <em>trampoline(addTo)(5)</em> ejecutando <em>addTo(5, 0)</em><br>\nComo el valor no es cero retorna la función anónima que ejecutaria de nuevo <em>addTo</em><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.33.21.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.33.21\"></p>\n<ol start=\"4\">\n<li><strong>Se ejecuta la función anónima que a su vez ejecuta <em>addTo(4, 5)</em></strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.34.00.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.34.00\"></li>\n</ol>\n<p>Esto devuelve de nuevo una función anónima, pero como tal su ejecución termina por lo que <em>addTo</em> sale del call stack<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.35.45.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.35.45\"></p>\n<p>Y lo mismo sucede con la función anónima que su ejecución ha terminado y sale del call stack<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.36.02.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.36.02\"></p>\n<ol start=\"5\">\n<li><strong>Como el resultado de todo esto sigue siendo una función nuestro trampoline vuelve a ejecutar la función anónima que ha recibido</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.38.09.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.38.09\"></li>\n</ol>\n<p>Donde a su vez se ejecuta <strong>addTo(3, 9)</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.38.19.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.38.19\"></p>\n<ol start=\"6\">\n<li>\n<p><strong>Este proceso se repite hasta que el parámetro number === 0 donde termina la ejecución de la función anónima dentro de trampoline</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.40.34.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.40.34\"></p>\n</li>\n<li>\n<p><strong>Se ejecuta el resultado de <em>console.log(trampoline(addTo)(5))</em> que nos muestra 15</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.40.51.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.40.51\"></p>\n</li>\n<li>\n<p><strong>Se ejecuta <em>finish()</em></strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.41.04.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.41.04\"></p>\n</li>\n</ol>\n<p>Entra dentro del call stack</p>\n<ol start=\"9\">\n<li><strong>Ejecuta el console.log dentro de la función finish</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.41.15.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.41.15\"></li>\n</ol>\n<p>Y la ejecución de nuestro programa o script termina</p>\n<p>Como vemos esto es un <em>truquillo</em> que hace que no saturemos el call stack de ejecuciones pendientes, que cubre la necesidad que tenemos aunque como digo no es algo que me convenza mucho.</p>\n<p>Esta es una de las formas que tenemos para evitar el <em>Maximum call stack</em>, en los siguientes post veremos otras posibles soluciones, algunas más sencillas otras más complejas, pero nos serviran para entender del todo como funciona el call stack.</p>\n<p>Nos vemos en el siguiente un abrazoooooo</p>\n<!--kg-card-end: markdown-->","url":"https://jlgarcia.fulldev.ninja/js-algoritmos-y-estructuras-de-datos-vi-la-recursividad-y-como-resolver-el-problema/","canonical_url":null,"uuid":"37ff4a5a-7e66-48c9-9a31-25cdc885dc1b","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"5fbc0b8ba6c0f5058bff47fa","reading_time":4,"send_email_when_published":false,"email_subject":null,"childHtmlRehype":{"html":"<!--kg-card-begin: markdown--><p>Ya vimos en el post anterior cual es el problema principal que podemos tener en JavaScript a la hora de usar la recursividad. En un primer momento lo más probable es que nunca nos encontremos con este problema a no ser que trabajemos con una gran cantidad de datos, pero aún así, creo que ver como se soluciona este problema puede hacernos entender algunas cosas del funcionamiento de Javascript y como podemos usarlas para cualquier otro problema que nos encontremos.</p>\n<p>Para resolver el problema de <em>\"Maximum call stack...\"</em> existen varias formas, veremos la mayoría aunque alguna puede que no me guste mucho.</p>\n<p>Vamos con la primera <strong>Trampoline</strong></p>\n<h3 id=\"trampoline\">Trampoline</h3>\n<p>Esta se fue extendiendo como una buena posibilidad para resolver el problema, pero personalmente a mí no me convence demasiado, creo que nos salimos un poco de la pureza del concepto de la recursividad pensando en su planteamiento más funcional. Veamos el código en cuestión:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">trampoline</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">fn</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token operator\">...</span>args</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">let</span> result <span class=\"token operator\">=</span> <span class=\"token function\">fn</span><span class=\"token punctuation\">(</span><span class=\"token operator\">...</span>args<span class=\"token punctuation\">)</span>\n  <span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">typeof</span> result <span class=\"token operator\">===</span> <span class=\"token string\">'function'</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    result <span class=\"token operator\">=</span> <span class=\"token function\">result</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token keyword\">return</span> result\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">number<span class=\"token punctuation\">,</span> accum <span class=\"token operator\">=</span> <span class=\"token number\">0</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>number <span class=\"token operator\">===</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t\t<span class=\"token keyword\">return</span> accum\n\t<span class=\"token punctuation\">}</span>\n\t<span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span>number <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> number <span class=\"token operator\">+</span> accum<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">finish</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Finished'</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\nconsole<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token function\">trampoline</span><span class=\"token punctuation\">(</span>addTo<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token number\">5</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n<span class=\"token function\">finish</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n</code></pre></div>\n<p>Más de uno se hará una idea de lo que realmente estamos haciendo en este caso y como cambia con respecto al ejemplo del post anterior sobre recursividad.<br>\nEn este ejemplo tenemos una función <strong>addTo</strong> que no se llama a si misma, si no que, según el caso llama a una función anónima que la vuelve a llamar. Pero claro no podemos llamar solo a la función <strong>addTo</strong> ya que en la primera ejecución simplemente devolvería una función que no se ejecuta y terminaría nuestro programa. Lo que hacemos es crear una función <strong>trampoline</strong> que encapsularía cualquier otra donde queramos usar la recursividad. Esta función lo que hace es controlar si la respuesta es una función que debemos que espera ejecutarse o no, en resumen, trampoline es una función que se encarga o de devolver un resultado si se ha cumplido nuestro <em>caso base</em> o de ejecutar de nuevo la función, veamos ahora lo que pasa en nuestro <em>call stack</em>.</p>\n<ol>\n<li><strong>Se ejecuta <em>trampoline</em></strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.21.36.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.21.36\"></li>\n</ol>\n<p>En cuanto a ejecutar, me refiero a, entre en el call stack y se ejecuta directamente.<br>\nEsto es una función con currificación, si nos fijamos lo que le pasamos como parámetro a <em>trampoline</em> es la función que queremos ejecutar, es decir, <em>addTo</em>.</p>\n<ol start=\"2\">\n<li><strong>Se ejecuta <em>trampoline(addTo)(5)</em></strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.27.10.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.27.10\"></li>\n</ol>\n<p>Entra <strong>trampoline(addTo)(5)</strong> al call stack y comienza a ejecutarse, aquí como tenemos un bucle while donde se ejecutan otros métodos, veremos como el call stack crece</p>\n<ol start=\"3\">\n<li><strong>Se ejecuta por primera vez <em>addTo</em> con el valor 5</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.29.38.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.29.38\"></li>\n</ol>\n<p>Como vemos estamos dentro de <em>trampoline(addTo)(5)</em> ejecutando <em>addTo(5, 0)</em><br>\nComo el valor no es cero retorna la función anónima que ejecutaria de nuevo <em>addTo</em><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.33.21.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.33.21\"></p>\n<ol start=\"4\">\n<li><strong>Se ejecuta la función anónima que a su vez ejecuta <em>addTo(4, 5)</em></strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.34.00.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.34.00\"></li>\n</ol>\n<p>Esto devuelve de nuevo una función anónima, pero como tal su ejecución termina por lo que <em>addTo</em> sale del call stack<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.35.45.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.35.45\"></p>\n<p>Y lo mismo sucede con la función anónima que su ejecución ha terminado y sale del call stack<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.36.02.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.36.02\"></p>\n<ol start=\"5\">\n<li><strong>Como el resultado de todo esto sigue siendo una función nuestro trampoline vuelve a ejecutar la función anónima que ha recibido</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.38.09.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.38.09\"></li>\n</ol>\n<p>Donde a su vez se ejecuta <strong>addTo(3, 9)</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.38.19.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.38.19\"></p>\n<ol start=\"6\">\n<li>\n<p><strong>Este proceso se repite hasta que el parámetro number === 0 donde termina la ejecución de la función anónima dentro de trampoline</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.40.34.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.40.34\"></p>\n</li>\n<li>\n<p><strong>Se ejecuta el resultado de <em>console.log(trampoline(addTo)(5))</em> que nos muestra 15</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.40.51.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.40.51\"></p>\n</li>\n<li>\n<p><strong>Se ejecuta <em>finish()</em></strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.41.04.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.41.04\"></p>\n</li>\n</ol>\n<p>Entra dentro del call stack</p>\n<ol start=\"9\">\n<li><strong>Ejecuta el console.log dentro de la función finish</strong><br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.41.15.png\" alt=\"Captura-de-pantalla-2020-12-12-a-las-14.41.15\"></li>\n</ol>\n<p>Y la ejecución de nuestro programa o script termina</p>\n<p>Como vemos esto es un <em>truquillo</em> que hace que no saturemos el call stack de ejecuciones pendientes, que cubre la necesidad que tenemos aunque como digo no es algo que me convenza mucho.</p>\n<p>Esta es una de las formas que tenemos para evitar el <em>Maximum call stack</em>, en los siguientes post veremos otras posibles soluciones, algunas más sencillas otras más complejas, pero nos serviran para entender del todo como funciona el call stack.</p>\n<p>Nos vemos en el siguiente un abrazoooooo</p>\n<!--kg-card-end: markdown-->","htmlAst":{"type":"root","children":[{"type":"comment","value":"kg-card-begin: markdown"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Ya vimos en el post anterior cual es el problema principal que podemos tener en JavaScript a la hora de usar la recursividad. En un primer momento lo más probable es que nunca nos encontremos con este problema a no ser que trabajemos con una gran cantidad de datos, pero aún así, creo que ver como se soluciona este problema puede hacernos entender algunas cosas del funcionamiento de Javascript y como podemos usarlas para cualquier otro problema que nos encontremos."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Para resolver el problema de "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"\"Maximum call stack...\""}]},{"type":"text","value":" existen varias formas, veremos la mayoría aunque alguna puede que no me guste mucho."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vamos con la primera "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Trampoline"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"trampoline"},"children":[{"type":"text","value":"Trampoline"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Esta se fue extendiendo como una buena posibilidad para resolver el problema, pero personalmente a mí no me convence demasiado, creo que nos salimos un poco de la pureza del concepto de la recursividad pensando en su planteamiento más funcional. Veamos el código en cuestión:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function-variable","function"]},"children":[{"type":"text","value":"trampoline"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"fn"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"text","value":"args"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" result "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fn"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"text","value":"args"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"while"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"typeof"}]},{"type":"text","value":" result "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'function'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    result "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"result"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" result\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"number"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" accum "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" accum\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"+"}]},{"type":"text","value":" accum"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"finish"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Finished'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\nconsole"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"trampoline"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"addTo"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"5"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"finish"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Más de uno se hará una idea de lo que realmente estamos haciendo en este caso y como cambia con respecto al ejemplo del post anterior sobre recursividad."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nEn este ejemplo tenemos una función "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"addTo"}]},{"type":"text","value":" que no se llama a si misma, si no que, según el caso llama a una función anónima que la vuelve a llamar. Pero claro no podemos llamar solo a la función "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"addTo"}]},{"type":"text","value":" ya que en la primera ejecución simplemente devolvería una función que no se ejecuta y terminaría nuestro programa. Lo que hacemos es crear una función "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"trampoline"}]},{"type":"text","value":" que encapsularía cualquier otra donde queramos usar la recursividad. Esta función lo que hace es controlar si la respuesta es una función que debemos que espera ejecutarse o no, en resumen, trampoline es una función que se encarga o de devolver un resultado si se ha cumplido nuestro "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"caso base"}]},{"type":"text","value":" o de ejecutar de nuevo la función, veamos ahora lo que pasa en nuestro "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"call stack"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Se ejecuta "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"trampoline"}]}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.21.36.png","alt":"Captura-de-pantalla-2020-12-12-a-las-14.21.36"},"children":[]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En cuanto a ejecutar, me refiero a, entre en el call stack y se ejecuta directamente."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nEsto es una función con currificación, si nos fijamos lo que le pasamos como parámetro a "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"trampoline"}]},{"type":"text","value":" es la función que queremos ejecutar, es decir, "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"addTo"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{"start":2},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Se ejecuta "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"trampoline(addTo)(5)"}]}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.27.10.png","alt":"Captura-de-pantalla-2020-12-12-a-las-14.27.10"},"children":[]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Entra "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"trampoline(addTo)(5)"}]},{"type":"text","value":" al call stack y comienza a ejecutarse, aquí como tenemos un bucle while donde se ejecutan otros métodos, veremos como el call stack crece"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{"start":3},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Se ejecuta por primera vez "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"addTo"}]},{"type":"text","value":" con el valor 5"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.29.38.png","alt":"Captura-de-pantalla-2020-12-12-a-las-14.29.38"},"children":[]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como vemos estamos dentro de "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"trampoline(addTo)(5)"}]},{"type":"text","value":" ejecutando "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"addTo(5, 0)"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nComo el valor no es cero retorna la función anónima que ejecutaria de nuevo "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.33.21.png","alt":"Captura-de-pantalla-2020-12-12-a-las-14.33.21"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{"start":4},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Se ejecuta la función anónima que a su vez ejecuta "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"addTo(4, 5)"}]}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.34.00.png","alt":"Captura-de-pantalla-2020-12-12-a-las-14.34.00"},"children":[]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Esto devuelve de nuevo una función anónima, pero como tal su ejecución termina por lo que "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"addTo"}]},{"type":"text","value":" sale del call stack"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.35.45.png","alt":"Captura-de-pantalla-2020-12-12-a-las-14.35.45"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y lo mismo sucede con la función anónima que su ejecución ha terminado y sale del call stack"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.36.02.png","alt":"Captura-de-pantalla-2020-12-12-a-las-14.36.02"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{"start":5},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Como el resultado de todo esto sigue siendo una función nuestro trampoline vuelve a ejecutar la función anónima que ha recibido"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.38.09.png","alt":"Captura-de-pantalla-2020-12-12-a-las-14.38.09"},"children":[]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Donde a su vez se ejecuta "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"addTo(3, 9)"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.38.19.png","alt":"Captura-de-pantalla-2020-12-12-a-las-14.38.19"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{"start":6},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Este proceso se repite hasta que el parámetro number === 0 donde termina la ejecución de la función anónima dentro de trampoline"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.40.34.png","alt":"Captura-de-pantalla-2020-12-12-a-las-14.40.34"},"children":[]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Se ejecuta el resultado de "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"console.log(trampoline(addTo)(5))"}]},{"type":"text","value":" que nos muestra 15"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.40.51.png","alt":"Captura-de-pantalla-2020-12-12-a-las-14.40.51"},"children":[]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Se ejecuta "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"finish()"}]}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.41.04.png","alt":"Captura-de-pantalla-2020-12-12-a-las-14.41.04"},"children":[]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Entra dentro del call stack"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{"start":9},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Ejecuta el console.log dentro de la función finish"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/12/Captura-de-pantalla-2020-12-12-a-las-14.41.15.png","alt":"Captura-de-pantalla-2020-12-12-a-las-14.41.15"},"children":[]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y la ejecución de nuestro programa o script termina"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como vemos esto es un "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"truquillo"}]},{"type":"text","value":" que hace que no saturemos el call stack de ejecuciones pendientes, que cubre la necesidad que tenemos aunque como digo no es algo que me convenza mucho."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Esta es una de las formas que tenemos para evitar el "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Maximum call stack"}]},{"type":"text","value":", en los siguientes post veremos otras posibles soluciones, algunas más sencillas otras más complejas, pero nos serviran para entender del todo como funciona el call stack."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Nos vemos en el siguiente un abrazoooooo"}]},{"type":"text","value":"\n"},{"type":"comment","value":"kg-card-end: markdown"}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"trampoline","heading":"Trampoline"}]},"featureImageSharp":{"base":"unordered-3192273_640.png","publicURL":"/static/e92df4805fb46ec1f6bec181d2305365/unordered-3192273_640.png","imageMeta":{"width":640,"height":512},"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFG0lEQVQ4ywEQBe/6APG/tx3SpZ5Y2+PkQNzf3UjCw89E2M6jZubUibvJxK5Yk5/RHmd0qxNMWpUXsLO/LLe5xT+corsvv7++MmxsaxaZmYUXj4+WHsrKyjrNzc1HANSJfnXTZVT/1X5wp7K+vUSttMg40cSUb+zYh97by4ie0smidOHVpIbbzpWb7Nybsuvbmrbd0ZKAnp/khImK5tyWltuK4uHGPOXl6E3NyMdIAJFqZDnPkIiCwW5inMx1abl/j3YbtLb/AOjCOwXl1IRn2MmFntzNk5Tw46uQ493CYMS+olvt2X+avrSnpo6R6KCEhNulmZrkhs3SsikAABILAMfLzkae0MIY/6TMANl3X5vGi5ajeYjzhYiH66WJi+eaq7TzQuTZqG3v3I+008OFfpKk8ie0pm0n792VubCzwjPOzcE9hofluLOt43/Ue2F8ANfWxzZsXLEeh5X/UKZvjFq/eo3ml6HgedPLukaUk+KxjIvdlPnhcoXu2pwW6tWCl8/Iq1Lp15Cv5NacgElUgxje2r4yvcLqYZeH0tfZdGPhALu70USCg+mpgobwgoyG49zFeobjqqbhhYCO6YmDh+SynZ3VX+bUg4Dq1oeN7NiHxOjXj8jk0XNXfoaCFL29wE7Lx8dK0eznLZB8yaHSgH3MAJuc5qKGhuCF3tmJGo2S6rLIdnrJpYq+sLCIr8LKrbdquMG3RJuZo0vHu4eC6NeQy9HPwUuJjNporKzXYbuzoTe1uLtHuLe0P9BrY8C/fYF/AI+Q58Kur9NhvLfDQ3+K8pXFeW9m3nJZ2d1mRoLUb1ydv8HBKcPc+Cu1qoeG8+med5KY8HOYl+bKjo3nvwBn/w6J0MgV1nhjuayBsuFPctxCAIqK7qybm8txAAAAAXyG8Im3kraj2nBY0M9vZazlcWFlAAAADkseE59cLiD4TiMHc3570auip+BMkJnslKZ3q5PXYkie0GhZ4bR9ntm4na5oAIeJ4GGOj+7S1dDJTqe951G3e5nrx2pZTs2/pT+ZjH9IUSohtkYkGP9XJBf/WCIR/1gwNfV2ds+lv3SH1M97csHfiWiGynJ1za10ncfifGW3AOvajLKkn8qdgYLtx7LA8WbegnGkmn2+vJKn/39iRVHMXjcn/z87N/l/ZFP7OSol/0MsHrvEbG2usHef4ouY+aGJnvF1rn+ozdF3ccLMeGqWAOzZjN7444OryLyvuH2K+8C8iZ/U1IJ2oG+u/zB5ZHl8iHBd/6eWifvKqI3/npGF/ZR5bf/EbW3an7DGK6Sl5YuLiuf/jZb2obahhjO1vMJGAPLflS795oUW9+N/ld/QjMXYyJr43I1t9MdNJzUAOAADpodx58Gfh/+2pJbpw6GH+qSGc9rPblisqpfDcKWj1N7m2KHVo57Myri4vFCtpqwTAP///wA4Qu8NgYTuetbLs6rk1pb/ybOjt9VvZ6nCe3R8vZ6Dvph6YsCjhXPzi3FcsbWUgL/SalawjoTgrpufzW7YypGa3c+i5uvbk3jw34+GANDPuTesrNtxi4zo4oqN87bDubTD5NiUt9zOonzEh23DnoF+8JF8gsfRpHz/jndr07mIdvXMfGaGn6TvrJiW2L23sMDh18qbg8urAAXq2pGqANDQ0EM2NjUTeHidH5qZlSEABVkJ/+eDL9fJh43Hpn/zn4ym/6Ca0f+tnbD+nYaO/7eXhvmxroxy7N6gf8u/p57XzJ513+DcQ7e3uzE9PDMO7sYRFrnPY/gAAAAASUVORK5CYII=","aspectRatio":1.25,"src":"/static/e92df4805fb46ec1f6bec181d2305365/8bef3/unordered-3192273_640.png","srcSet":"/static/e92df4805fb46ec1f6bec181d2305365/847ef/unordered-3192273_640.png 175w,\n/static/e92df4805fb46ec1f6bec181d2305365/91cba/unordered-3192273_640.png 350w,\n/static/e92df4805fb46ec1f6bec181d2305365/8bef3/unordered-3192273_640.png 640w","srcWebp":"/static/e92df4805fb46ec1f6bec181d2305365/1ea2e/unordered-3192273_640.webp","srcSetWebp":"/static/e92df4805fb46ec1f6bec181d2305365/9fca7/unordered-3192273_640.webp 175w,\n/static/e92df4805fb46ec1f6bec181d2305365/37a4e/unordered-3192273_640.webp 350w,\n/static/e92df4805fb46ec1f6bec181d2305365/1ea2e/unordered-3192273_640.webp 640w","sizes":"(max-width: 640px) 100vw, 640px"}}}}},{"node":{"id":"Ghost__Post__5c18a5012dd6610fd828cacd","title":"JS Algoritmos y  Estructuras de datos V: La recursividad y su pequeño problema en Javascript","slug":"js-algorithm-and-data-structures-recursion","featured":false,"feature_image":"https://jlgarcia.fulldev.ninja/assets/images/2020/11/unordered-3192273_640-2.png","excerpt":"Hablemos ahora de la Recursividad. A la gran mayoría por lo menos nos tiene que\nsonar ¿no?... por lo menos nos habrán dicho que es muy chula, que mola usarla,\nque porque no lo pruebas... pues bien he de coincidir con casi cualquier cosa\nbuena que se diga sobre este concepto, aunque claro lo suyo es usarlo cuando\ntoque y tenga sentido (pero eso es otra historia).\n\nPor ahora veremos que es esto de la recursividad, para que nos sirve y cual es\nel problema que nos generará a la larga (y como resolve","custom_excerpt":null,"visibility":"public","created_at_pretty":"18 Dec 2018","published_at_pretty":"7 Dec 2020","updated_at_pretty":"19 Jan 2021","created_at":"2018-12-18T08:42:57.000+01:00","published_at":"2020-12-07T10:33:00.000+01:00","updated_at":"2021-01-19T21:10:34.000+01:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"Perfil.jpg","publicURL":"/static/b0de6281fb28a266510b3b09b9243e5a/Perfil.jpg","imageMeta":{"width":307,"height":307},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUDBAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGzw6zC6zHn+cLYP//EAB0QAAICAQUAAAAAAAAAAAAAAAEDAAIEEyEiIzL/2gAIAQEAAQUCifca8KgcKWVfUpkHsG5pxX//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAdEAACAgEFAAAAAAAAAAAAAAAAARARcQISIUFR/9oACAEBAAY/AhU88xkb7N06a8P/xAAcEAEAAwEAAwEAAAAAAAAAAAABABEhMUFRYXH/2gAIAQEAAT8hR2pq40aqb+xIAeXibhW9JXr8joF4TBcSNe0//9oADAMBAAIAAwAAABDzDwD/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAcEAEAAgIDAQAAAAAAAAAAAAABABEhUTFhcfD/2gAIAQEAAT8QyItrELaTlatLwU63MvEW6vUNdy4LZQDn7iVApV9VLtANdWwKkuYq4Er1VZ//2Q==","aspectRatio":1,"src":"/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg","srcSet":"/static/b0de6281fb28a266510b3b09b9243e5a/f340b/Perfil.jpg 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/22d64/Perfil.jpg 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/aa249/Perfil.jpg 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/0dc33/Perfil.jpg 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/60667/Perfil.jpg 307w","srcWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp","srcSetWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/59cda/Perfil.webp 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/7da75/Perfil.webp 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f282e/Perfil.webp 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/a7b21/Perfil.webp 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f59af/Perfil.webp 307w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"algoritmos","url":"https://jlgarcia.fulldev.ninja/tag/algoritmos/","name":"algoritmos","visibility":"public","feature_image":null,"description":null,"meta_title":null,"meta_description":null,"featureImageSharp":null},"tags":[{"slug":"algoritmos","url":"https://jlgarcia.fulldev.ninja/tag/algoritmos/","name":"algoritmos","visibility":"public","feature_image":null,"description":null,"meta_title":null,"meta_description":null,"featureImageSharp":null},{"slug":"javascript","url":"https://jlgarcia.fulldev.ninja/tag/javascript/","name":"javascript","visibility":"public","feature_image":null,"description":null,"meta_title":null,"meta_description":null,"featureImageSharp":null}],"plaintext":"Hablemos ahora de la Recursividad. A la gran mayoría por lo menos nos tiene que\nsonar ¿no?... por lo menos nos habrán dicho que es muy chula, que mola usarla,\nque porque no lo pruebas... pues bien he de coincidir con casi cualquier cosa\nbuena que se diga sobre este concepto, aunque claro lo suyo es usarlo cuando\ntoque y tenga sentido (pero eso es otra historia).\n\nPor ahora veremos que es esto de la recursividad, para que nos sirve y cual es\nel problema que nos generará a la larga (y como resolverlo) esto en nuestro\nquerido Javascript.\n\nRecursividad\nNo me voy a extender en explicaciones técnicas en este caso (profundizaré más en\nel post de la línea de javascript funcional), por lo que, en palabras simples,\nes la capacidad de una función de llamarse a si misma. Esto es más un concepto\nde programación funcional, pero debido a que las funciones en javascript se\npueden tratar como cualquier otro objeto (ciudadano de primera clase), es decir,\nque se puede pasar por parámetro, retornar dentro de otra función.... y todo lo\nque se nos ocurra, podemos hacer uso de la recursión también.\n\nAlgunos ejemplos de su uso podrian ser: Recorrer un sistema de ficheros (abrir\nprimera carpeta, recorrer lo que hay dentro y si encuentra una carpeta la abre y\nrecorre...y asi sucesivamente), se suele ver en la típica resolución de\nproblemas sobre los números de Fibonacci (que es y ejemplos aquí\n[https://medium.com/developers-writing/fibonacci-sequence-algorithm-in-javascript-b253dc7e320e]\n) o en general cualquier problema que requiera repetir lógica sobre un mismo\nelemento (y no necesitemos o no tenga sentido funcional que usemos un bucle de\nlos habituales)\n\nVeamos cuales son los detalles de una función recursiva. Ya hemos comentado que\nen la teoría se supone que es una función que se llama a si misma, como por\nejemplo\n\nfunction addTo (number) {\n\treturn number + addTo(number - 1)\n}\n\naddTo(10)\n\n\nLa teoría de la función sería que queremos sumar los números desde 0 hasta el\nnúmero dado. Visualmente tiene sentido, ¿no?, sumamos el número que recibimos\nprimero que sería el 10 y luego llamamos a la misma función para que use el 9 y\nasí sucesivamente. Pero claro si nos fijamos bien aquí tenemos un problema, si\nejecutaramos esto tendriamos un bucle infinito porque en ningún momento le\nindicamos cuando tiene que parar. Lo que le falta a esta función es lo que se\nconoce como caso base.\n\nEl caso base es la unidad mínima que debe devolver una función recursiva, si\npensamos en lo que queríamos hacer que era sumar del 0 al 10, en este caso nos\nfalta indicarle que cuando llegue a 0 nos devuelva el número, este sería nuestro\ncaso base, siempre debe tener un caso base.\n\nfunction addTo(number) {\n\tif (number === 0) {\n\t\treturn number\n\t}\n\treturn number + addTo(number - 1)\n}\n\naddTo(10)\n\n\nSi ahora ejecutamos esto todo iria bien y nos debería devolver 55. Esto es un\ncaso muy sencillo para explicar que es la recursión pero veamos rápidamente que\nes lo que lo pasa por debajo.\n\nPara ello lo primero es repasar que es el call stack. El call stack o pila de\nllamadas (lo defino a mi rollo por simplicicad) son las funciones que se tienen\nque ejecutar (con estructura LIFO) dentro de un Task del event loop. En el\npróximo post profundizaremos más en que es cada cosa y el flujo que sigue el\neventloop, con lo que nos tenemos que quedar ahora mismo es que el call stack es\nel trabajo que tiene pendiente javascript para poder pasar a la siguiente tarea\n(es decir que nuestro thread esta bloqueado hasta que termine).\n\nPara verlo bien vamos a usar una herramienta que me he encontrado (grandisima\nayuda para entender esto visualmente ya lo veremos, agradecer a los creadores)\nque es jsv9000 [https://www.jsv9000.app/]. Esta herramienta nos permite\ncomprobar visualmente lo que pasa dentro de nuestro eventloop en cada una de sus\nQueues.\n\nLo que haremos será añadir el código siguiente y darle a run:\n\nfunction addTo(number) {\n\tif (number === 0) {\n\t\treturn number\n\t}\n\treturn number + addTo(number - 1)\n}\n\nfunction finish () {\n  console.log('Finished')\n}\n\naddTo(5)\nfinish()\n\n\nLo que hace la herramienta es indicarnos en que puesto está nuestro código y que\nha ido pasando por dentro paso a paso, por lo que tenemos que ir dandole a step.\nSi le damos 6 veces (como le hemos indicado que hasta 5 y empezamos en el 0)\nvemos como el código lo único que ha hecho es incluir 6 llamadas en el call\nstack de la función de suma en la fase de evaluación\n\n\n\nSi le continuamos dando a step vemos como se va vaciando el call stack de la\nfunción y lo siguiente es el método finish que nos muestra el resultado del \nconsole.log. En este caso lo que vemos es que nuestra función recursiva va\nacumulando llamadas en el call stack hasta que llega al caso base y empieza a\ndevolver datos y a vaciar. Si lo queremos ver más claro añadimos unos logs\n\nfunction addTo(number) {\n\tif (number === 0) {\n\t  console.log(0)\n\t\treturn number\n\t}\n\tconst result = number + addTo(number - 1)\n\tconsole.log('result: ', result)\n\treturn result\n}\n\nfunction finish () {\n  console.log('Finished')\n}\n\naddTo(5)\nfinish()\n\n\nY podemos ver en acción realmente donde estamos\n\n\n\nUna vez entendido esto, ahora os planteo el gran problema que resolveremos en\npróximos posts. Cambiemos el código por lo siguiente pero no recomiendo\nejecutarlo en la herramienta que tardaría muchisimo, ejecutarlo en la consola\ndel navegador, en un fichero de node o donde más os guste\n\nfunction addTo(number) {\n\tif (number === 0) {\n\t\treturn number\n\t}\n\treturn number + addTo(number - 1)\n}\n\nconsole.log(addTo(100000))\n\n\nFijaos el número que he puesto 100000, esto nos debe dar un error como el\nsiguiente:\n\n\n\nEs decir hemos llegado al límite de acciones posibles dentro de la pila de\nllamadas, si nos planteamos lo que ocurria con 5, que teniamos 6 inclusiones el\ncall stack, ahora tendríamos 100001 (se que este número es muy grande pero\ndepende de lo que estemos haciendo o donde puede ser mucho menos, realmente\ninsisto en que es un error muy habitual). Este problema viene dado porque\njavascript no es un lenguaje orientado a este tipo de funciones, pero siempre\npodemos encontrarle solución, en los próximos post veremos como podemos\nsolucionar esto de muchas maneras, mientras tando plantear vosotros posibles\nsoluciones. Nos vemos en el siguiente un abrazoooooor","html":"<!--kg-card-begin: markdown--><p>Hablemos ahora de la <strong>Recursividad</strong>. A la gran mayoría por lo menos nos tiene que sonar ¿no?... por lo menos nos habrán dicho que es muy chula, que mola usarla, que porque no lo pruebas... pues bien he de coincidir con casi cualquier cosa buena que se diga sobre este concepto, aunque claro lo suyo es usarlo cuando toque y tenga sentido (pero eso es otra historia).</p>\n<p>Por ahora veremos que es esto de la recursividad, para que nos sirve y cual es el problema que nos generará a la larga (y como resolverlo) esto en nuestro querido <em>Javascript</em>.</p>\n<h3 id=\"recursividad\">Recursividad</h3>\n<p>No me voy a extender en explicaciones técnicas en este caso (profundizaré más en el post de la línea de javascript funcional), por lo que, en palabras simples, es la capacidad de una función de llamarse a si misma. Esto es más un concepto de programación funcional, pero debido a que las funciones en javascript se pueden tratar como cualquier otro objeto (ciudadano de primera clase), es decir, que se puede pasar por parámetro, retornar dentro de otra función.... y todo lo que se nos ocurra, podemos hacer uso de la recursión también.</p>\n<p>Algunos ejemplos de su uso podrian ser: Recorrer un sistema de ficheros (abrir primera carpeta, recorrer lo que hay dentro y si encuentra una carpeta la abre y recorre...y asi sucesivamente), se suele ver en la típica resolución de problemas sobre los números de <em>Fibonacci</em> (que es y ejemplos <a href=\"https://medium.com/developers-writing/fibonacci-sequence-algorithm-in-javascript-b253dc7e320e\">aquí</a>) o en general cualquier problema que requiera repetir lógica sobre un mismo elemento (y no necesitemos o no tenga sentido funcional que usemos un bucle de los habituales)</p>\n<p>Veamos cuales son los detalles de una función recursiva. Ya hemos comentado que en la teoría se supone que es una función que se llama a si misma, como por ejemplo</p>\n<pre><code class=\"language-javascript\">function addTo (number) {\n\treturn number + addTo(number - 1)\n}\n\naddTo(10)\n</code></pre>\n<p>La teoría de la función sería que queremos sumar los números desde 0 hasta el número dado. Visualmente tiene sentido, ¿no?, sumamos el número que recibimos primero que sería el 10 y luego llamamos a la misma función para que use el 9 y así sucesivamente. Pero claro si nos fijamos bien aquí tenemos un problema, si ejecutaramos esto tendriamos un <strong>bucle infinito</strong> porque en ningún momento le indicamos cuando tiene que parar. Lo que le falta a esta función es lo que se conoce como <strong>caso base</strong>.</p>\n<p>El <strong>caso base</strong> es la unidad mínima que debe devolver una función recursiva, si pensamos en lo que queríamos hacer que era sumar del 0 al 10, en este caso nos falta indicarle que cuando llegue a 0 nos devuelva el número, este sería nuestro caso base, <strong>siempre debe tener un caso base</strong>.</p>\n<pre><code class=\"language-javascript\">function addTo(number) {\n\tif (number === 0) {\n\t\treturn number\n\t}\n\treturn number + addTo(number - 1)\n}\n\naddTo(10)\n</code></pre>\n<p>Si ahora ejecutamos esto todo iria bien y nos debería devolver 55. Esto es un caso muy sencillo para explicar que es la recursión pero veamos rápidamente que es lo que lo pasa por debajo.</p>\n<p>Para ello lo primero es repasar que es el <strong>call stack</strong>. El <em>call stack</em> o <em>pila de llamadas</em> (lo defino a mi rollo por simplicicad) son las funciones que se tienen que ejecutar (con estructura <em>LIFO</em>) dentro de un <em>Task</em> del event loop. En el próximo post profundizaremos más en que es cada cosa y el flujo que sigue el eventloop, con lo que nos tenemos que quedar ahora mismo es que el <em>call stack</em> es el trabajo que tiene pendiente javascript para poder pasar a la siguiente tarea (es decir que nuestro thread esta bloqueado hasta que termine).</p>\n<p>Para verlo bien vamos a usar una herramienta que me he encontrado (grandisima ayuda para entender esto visualmente ya lo veremos, agradecer a los creadores) que es <a href=\"https://www.jsv9000.app/\">jsv9000</a>. Esta herramienta nos permite comprobar visualmente lo que pasa dentro de nuestro eventloop en cada una de sus Queues.</p>\n<p>Lo que haremos será añadir el código siguiente y darle a <strong>run</strong>:</p>\n<pre><code class=\"language-javascript\">function addTo(number) {\n\tif (number === 0) {\n\t\treturn number\n\t}\n\treturn number + addTo(number - 1)\n}\n\nfunction finish () {\n  console.log('Finished')\n}\n\naddTo(5)\nfinish()\n</code></pre>\n<p>Lo que hace la herramienta es indicarnos en que puesto está nuestro código y que ha ido pasando por dentro paso a paso, por lo que tenemos que ir dandole a <strong>step</strong>. Si le damos 6 veces (como le hemos indicado que hasta 5 y empezamos en el 0) vemos como el código lo único que ha hecho es incluir 6 llamadas en el call stack de la función de suma en la fase de <em>evaluación</em></p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/11/Captura-de-pantalla-2020-11-21-a-las-14.05.32.png\" alt=\"Captura-de-pantalla-2020-11-21-a-las-14.05.32\"></p>\n<p>Si le continuamos dando a <strong>step</strong> vemos como se va vaciando el call stack de la función y lo siguiente es el método <em>finish</em> que nos muestra el resultado del <em>console.log</em>. En este caso lo que vemos es que nuestra función recursiva va acumulando llamadas en el call stack hasta que llega al caso base y empieza a devolver datos y a vaciar. Si lo queremos ver más claro añadimos unos logs</p>\n<pre><code class=\"language-javascript\">function addTo(number) {\n\tif (number === 0) {\n\t  console.log(0)\n\t\treturn number\n\t}\n\tconst result = number + addTo(number - 1)\n\tconsole.log('result: ', result)\n\treturn result\n}\n\nfunction finish () {\n  console.log('Finished')\n}\n\naddTo(5)\nfinish()\n</code></pre>\n<p>Y podemos ver en acción realmente donde estamos</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/11/Captura-de-pantalla-2020-11-21-a-las-14.19.09.png\" alt=\"Captura-de-pantalla-2020-11-21-a-las-14.19.09\"></p>\n<p>Una vez entendido esto, ahora os planteo el gran problema que resolveremos en próximos posts. Cambiemos el código por lo siguiente pero no recomiendo ejecutarlo en la herramienta que tardaría muchisimo, ejecutarlo en la consola del navegador, en un fichero de node o donde más os guste</p>\n<pre><code class=\"language-javascript\">function addTo(number) {\n\tif (number === 0) {\n\t\treturn number\n\t}\n\treturn number + addTo(number - 1)\n}\n\nconsole.log(addTo(100000))\n</code></pre>\n<p>Fijaos el número que he puesto <strong>100000</strong>, esto nos debe dar un error como el siguiente:</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/11/Captura-de-pantalla-2020-11-21-a-las-14.23.21.png\" alt=\"Captura-de-pantalla-2020-11-21-a-las-14.23.21\"></p>\n<p>Es decir hemos llegado al límite de acciones posibles dentro de la pila de llamadas, si nos planteamos lo que ocurria con 5, que teniamos 6 inclusiones el call stack, ahora tendríamos 100001 (se que este número es muy grande pero depende de lo que estemos haciendo o donde puede ser mucho menos, realmente insisto en que es un error muy habitual). Este problema viene dado porque javascript no es un lenguaje orientado a este tipo de funciones, pero siempre podemos encontrarle solución, en los próximos post veremos como podemos solucionar esto de muchas maneras, mientras tando plantear vosotros posibles soluciones. Nos vemos en el siguiente un abrazoooooor</p>\n<!--kg-card-end: markdown-->","url":"https://jlgarcia.fulldev.ninja/js-algorithm-and-data-structures-recursion/","canonical_url":null,"uuid":"335a1d74-2ed5-419b-a074-834acf15eee0","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"5c18a5012dd6610fd828cacd","reading_time":5,"send_email_when_published":false,"email_subject":null,"childHtmlRehype":{"html":"<!--kg-card-begin: markdown--><p>Hablemos ahora de la <strong>Recursividad</strong>. A la gran mayoría por lo menos nos tiene que sonar ¿no?... por lo menos nos habrán dicho que es muy chula, que mola usarla, que porque no lo pruebas... pues bien he de coincidir con casi cualquier cosa buena que se diga sobre este concepto, aunque claro lo suyo es usarlo cuando toque y tenga sentido (pero eso es otra historia).</p>\n<p>Por ahora veremos que es esto de la recursividad, para que nos sirve y cual es el problema que nos generará a la larga (y como resolverlo) esto en nuestro querido <em>Javascript</em>.</p>\n<h3 id=\"recursividad\">Recursividad</h3>\n<p>No me voy a extender en explicaciones técnicas en este caso (profundizaré más en el post de la línea de javascript funcional), por lo que, en palabras simples, es la capacidad de una función de llamarse a si misma. Esto es más un concepto de programación funcional, pero debido a que las funciones en javascript se pueden tratar como cualquier otro objeto (ciudadano de primera clase), es decir, que se puede pasar por parámetro, retornar dentro de otra función.... y todo lo que se nos ocurra, podemos hacer uso de la recursión también.</p>\n<p>Algunos ejemplos de su uso podrian ser: Recorrer un sistema de ficheros (abrir primera carpeta, recorrer lo que hay dentro y si encuentra una carpeta la abre y recorre...y asi sucesivamente), se suele ver en la típica resolución de problemas sobre los números de <em>Fibonacci</em> (que es y ejemplos <a href=\"https://medium.com/developers-writing/fibonacci-sequence-algorithm-in-javascript-b253dc7e320e\">aquí</a>) o en general cualquier problema que requiera repetir lógica sobre un mismo elemento (y no necesitemos o no tenga sentido funcional que usemos un bucle de los habituales)</p>\n<p>Veamos cuales son los detalles de una función recursiva. Ya hemos comentado que en la teoría se supone que es una función que se llama a si misma, como por ejemplo</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token function\">addTo</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">number</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">return</span> number <span class=\"token operator\">+</span> <span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span>number <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">)</span>\n</code></pre></div>\n<p>La teoría de la función sería que queremos sumar los números desde 0 hasta el número dado. Visualmente tiene sentido, ¿no?, sumamos el número que recibimos primero que sería el 10 y luego llamamos a la misma función para que use el 9 y así sucesivamente. Pero claro si nos fijamos bien aquí tenemos un problema, si ejecutaramos esto tendriamos un <strong>bucle infinito</strong> porque en ningún momento le indicamos cuando tiene que parar. Lo que le falta a esta función es lo que se conoce como <strong>caso base</strong>.</p>\n<p>El <strong>caso base</strong> es la unidad mínima que debe devolver una función recursiva, si pensamos en lo que queríamos hacer que era sumar del 0 al 10, en este caso nos falta indicarle que cuando llegue a 0 nos devuelva el número, este sería nuestro caso base, <strong>siempre debe tener un caso base</strong>.</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">number</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>number <span class=\"token operator\">===</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t\t<span class=\"token keyword\">return</span> number\n\t<span class=\"token punctuation\">}</span>\n\t<span class=\"token keyword\">return</span> number <span class=\"token operator\">+</span> <span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span>number <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token number\">10</span><span class=\"token punctuation\">)</span>\n</code></pre></div>\n<p>Si ahora ejecutamos esto todo iria bien y nos debería devolver 55. Esto es un caso muy sencillo para explicar que es la recursión pero veamos rápidamente que es lo que lo pasa por debajo.</p>\n<p>Para ello lo primero es repasar que es el <strong>call stack</strong>. El <em>call stack</em> o <em>pila de llamadas</em> (lo defino a mi rollo por simplicicad) son las funciones que se tienen que ejecutar (con estructura <em>LIFO</em>) dentro de un <em>Task</em> del event loop. En el próximo post profundizaremos más en que es cada cosa y el flujo que sigue el eventloop, con lo que nos tenemos que quedar ahora mismo es que el <em>call stack</em> es el trabajo que tiene pendiente javascript para poder pasar a la siguiente tarea (es decir que nuestro thread esta bloqueado hasta que termine).</p>\n<p>Para verlo bien vamos a usar una herramienta que me he encontrado (grandisima ayuda para entender esto visualmente ya lo veremos, agradecer a los creadores) que es <a href=\"https://www.jsv9000.app/\">jsv9000</a>. Esta herramienta nos permite comprobar visualmente lo que pasa dentro de nuestro eventloop en cada una de sus Queues.</p>\n<p>Lo que haremos será añadir el código siguiente y darle a <strong>run</strong>:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">number</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>number <span class=\"token operator\">===</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t\t<span class=\"token keyword\">return</span> number\n\t<span class=\"token punctuation\">}</span>\n\t<span class=\"token keyword\">return</span> number <span class=\"token operator\">+</span> <span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span>number <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">finish</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Finished'</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token number\">5</span><span class=\"token punctuation\">)</span>\n<span class=\"token function\">finish</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n</code></pre></div>\n<p>Lo que hace la herramienta es indicarnos en que puesto está nuestro código y que ha ido pasando por dentro paso a paso, por lo que tenemos que ir dandole a <strong>step</strong>. Si le damos 6 veces (como le hemos indicado que hasta 5 y empezamos en el 0) vemos como el código lo único que ha hecho es incluir 6 llamadas en el call stack de la función de suma en la fase de <em>evaluación</em></p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/11/Captura-de-pantalla-2020-11-21-a-las-14.05.32.png\" alt=\"Captura-de-pantalla-2020-11-21-a-las-14.05.32\"></p>\n<p>Si le continuamos dando a <strong>step</strong> vemos como se va vaciando el call stack de la función y lo siguiente es el método <em>finish</em> que nos muestra el resultado del <em>console.log</em>. En este caso lo que vemos es que nuestra función recursiva va acumulando llamadas en el call stack hasta que llega al caso base y empieza a devolver datos y a vaciar. Si lo queremos ver más claro añadimos unos logs</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">number</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>number <span class=\"token operator\">===</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t  console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\n\t\t<span class=\"token keyword\">return</span> number\n\t<span class=\"token punctuation\">}</span>\n\t<span class=\"token keyword\">const</span> result <span class=\"token operator\">=</span> number <span class=\"token operator\">+</span> <span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span>number <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n\tconsole<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'result: '</span><span class=\"token punctuation\">,</span> result<span class=\"token punctuation\">)</span>\n\t<span class=\"token keyword\">return</span> result\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">finish</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Finished'</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token number\">5</span><span class=\"token punctuation\">)</span>\n<span class=\"token function\">finish</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n</code></pre></div>\n<p>Y podemos ver en acción realmente donde estamos</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/11/Captura-de-pantalla-2020-11-21-a-las-14.19.09.png\" alt=\"Captura-de-pantalla-2020-11-21-a-las-14.19.09\"></p>\n<p>Una vez entendido esto, ahora os planteo el gran problema que resolveremos en próximos posts. Cambiemos el código por lo siguiente pero no recomiendo ejecutarlo en la herramienta que tardaría muchisimo, ejecutarlo en la consola del navegador, en un fichero de node o donde más os guste</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">function</span> <span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">number</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>number <span class=\"token operator\">===</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t\t<span class=\"token keyword\">return</span> number\n\t<span class=\"token punctuation\">}</span>\n\t<span class=\"token keyword\">return</span> number <span class=\"token operator\">+</span> <span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span>number <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\nconsole<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token function\">addTo</span><span class=\"token punctuation\">(</span><span class=\"token number\">100000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n</code></pre></div>\n<p>Fijaos el número que he puesto <strong>100000</strong>, esto nos debe dar un error como el siguiente:</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2020/11/Captura-de-pantalla-2020-11-21-a-las-14.23.21.png\" alt=\"Captura-de-pantalla-2020-11-21-a-las-14.23.21\"></p>\n<p>Es decir hemos llegado al límite de acciones posibles dentro de la pila de llamadas, si nos planteamos lo que ocurria con 5, que teniamos 6 inclusiones el call stack, ahora tendríamos 100001 (se que este número es muy grande pero depende de lo que estemos haciendo o donde puede ser mucho menos, realmente insisto en que es un error muy habitual). Este problema viene dado porque javascript no es un lenguaje orientado a este tipo de funciones, pero siempre podemos encontrarle solución, en los próximos post veremos como podemos solucionar esto de muchas maneras, mientras tando plantear vosotros posibles soluciones. Nos vemos en el siguiente un abrazoooooor</p>\n<!--kg-card-end: markdown-->","htmlAst":{"type":"root","children":[{"type":"comment","value":"kg-card-begin: markdown"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Hablemos ahora de la "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Recursividad"}]},{"type":"text","value":". A la gran mayoría por lo menos nos tiene que sonar ¿no?... por lo menos nos habrán dicho que es muy chula, que mola usarla, que porque no lo pruebas... pues bien he de coincidir con casi cualquier cosa buena que se diga sobre este concepto, aunque claro lo suyo es usarlo cuando toque y tenga sentido (pero eso es otra historia)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Por ahora veremos que es esto de la recursividad, para que nos sirve y cual es el problema que nos generará a la larga (y como resolverlo) esto en nuestro querido "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Javascript"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"recursividad"},"children":[{"type":"text","value":"Recursividad"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"No me voy a extender en explicaciones técnicas en este caso (profundizaré más en el post de la línea de javascript funcional), por lo que, en palabras simples, es la capacidad de una función de llamarse a si misma. Esto es más un concepto de programación funcional, pero debido a que las funciones en javascript se pueden tratar como cualquier otro objeto (ciudadano de primera clase), es decir, que se puede pasar por parámetro, retornar dentro de otra función.... y todo lo que se nos ocurra, podemos hacer uso de la recursión también."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Algunos ejemplos de su uso podrian ser: Recorrer un sistema de ficheros (abrir primera carpeta, recorrer lo que hay dentro y si encuentra una carpeta la abre y recorre...y asi sucesivamente), se suele ver en la típica resolución de problemas sobre los números de "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Fibonacci"}]},{"type":"text","value":" (que es y ejemplos "},{"type":"element","tagName":"a","properties":{"href":"https://medium.com/developers-writing/fibonacci-sequence-algorithm-in-javascript-b253dc7e320e"},"children":[{"type":"text","value":"aquí"}]},{"type":"text","value":") o en general cualquier problema que requiera repetir lógica sobre un mismo elemento (y no necesitemos o no tenga sentido funcional que usemos un bucle de los habituales)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Veamos cuales son los detalles de una función recursiva. Ya hemos comentado que en la teoría se supone que es una función que se llama a si misma, como por ejemplo"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"number"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"+"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"10"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"La teoría de la función sería que queremos sumar los números desde 0 hasta el número dado. Visualmente tiene sentido, ¿no?, sumamos el número que recibimos primero que sería el 10 y luego llamamos a la misma función para que use el 9 y así sucesivamente. Pero claro si nos fijamos bien aquí tenemos un problema, si ejecutaramos esto tendriamos un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"bucle infinito"}]},{"type":"text","value":" porque en ningún momento le indicamos cuando tiene que parar. Lo que le falta a esta función es lo que se conoce como "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"caso base"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"El "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"caso base"}]},{"type":"text","value":" es la unidad mínima que debe devolver una función recursiva, si pensamos en lo que queríamos hacer que era sumar del 0 al 10, en este caso nos falta indicarle que cuando llegue a 0 nos devuelva el número, este sería nuestro caso base, "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"siempre debe tener un caso base"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"number"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" number\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"+"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"10"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Si ahora ejecutamos esto todo iria bien y nos debería devolver 55. Esto es un caso muy sencillo para explicar que es la recursión pero veamos rápidamente que es lo que lo pasa por debajo."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Para ello lo primero es repasar que es el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"call stack"}]},{"type":"text","value":". El "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"call stack"}]},{"type":"text","value":" o "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"pila de llamadas"}]},{"type":"text","value":" (lo defino a mi rollo por simplicicad) son las funciones que se tienen que ejecutar (con estructura "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"LIFO"}]},{"type":"text","value":") dentro de un "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Task"}]},{"type":"text","value":" del event loop. En el próximo post profundizaremos más en que es cada cosa y el flujo que sigue el eventloop, con lo que nos tenemos que quedar ahora mismo es que el "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"call stack"}]},{"type":"text","value":" es el trabajo que tiene pendiente javascript para poder pasar a la siguiente tarea (es decir que nuestro thread esta bloqueado hasta que termine)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Para verlo bien vamos a usar una herramienta que me he encontrado (grandisima ayuda para entender esto visualmente ya lo veremos, agradecer a los creadores) que es "},{"type":"element","tagName":"a","properties":{"href":"https://www.jsv9000.app/"},"children":[{"type":"text","value":"jsv9000"}]},{"type":"text","value":". Esta herramienta nos permite comprobar visualmente lo que pasa dentro de nuestro eventloop en cada una de sus Queues."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Lo que haremos será añadir el código siguiente y darle a "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"run"}]},{"type":"text","value":":"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"number"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" number\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"+"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"finish"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Finished'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"5"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"finish"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Lo que hace la herramienta es indicarnos en que puesto está nuestro código y que ha ido pasando por dentro paso a paso, por lo que tenemos que ir dandole a "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"step"}]},{"type":"text","value":". Si le damos 6 veces (como le hemos indicado que hasta 5 y empezamos en el 0) vemos como el código lo único que ha hecho es incluir 6 llamadas en el call stack de la función de suma en la fase de "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"evaluación"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/11/Captura-de-pantalla-2020-11-21-a-las-14.05.32.png","alt":"Captura-de-pantalla-2020-11-21-a-las-14.05.32"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Si le continuamos dando a "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"step"}]},{"type":"text","value":" vemos como se va vaciando el call stack de la función y lo siguiente es el método "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"finish"}]},{"type":"text","value":" que nos muestra el resultado del "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"console.log"}]},{"type":"text","value":". En este caso lo que vemos es que nuestra función recursiva va acumulando llamadas en el call stack hasta que llega al caso base y empieza a devolver datos y a vaciar. Si lo queremos ver más claro añadimos unos logs"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"number"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t  console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\t\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" number\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" result "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"+"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\tconsole"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'result: '"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" result"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" result\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"finish"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Finished'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"5"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"finish"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y podemos ver en acción realmente donde estamos"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/11/Captura-de-pantalla-2020-11-21-a-las-14.19.09.png","alt":"Captura-de-pantalla-2020-11-21-a-las-14.19.09"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Una vez entendido esto, ahora os planteo el gran problema que resolveremos en próximos posts. Cambiemos el código por lo siguiente pero no recomiendo ejecutarlo en la herramienta que tardaría muchisimo, ejecutarlo en la consola del navegador, en un fichero de node o donde más os guste"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"number"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" number\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"+"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"number "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\nconsole"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addTo"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"100000"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Fijaos el número que he puesto "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"100000"}]},{"type":"text","value":", esto nos debe dar un error como el siguiente:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2020/11/Captura-de-pantalla-2020-11-21-a-las-14.23.21.png","alt":"Captura-de-pantalla-2020-11-21-a-las-14.23.21"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Es decir hemos llegado al límite de acciones posibles dentro de la pila de llamadas, si nos planteamos lo que ocurria con 5, que teniamos 6 inclusiones el call stack, ahora tendríamos 100001 (se que este número es muy grande pero depende de lo que estemos haciendo o donde puede ser mucho menos, realmente insisto en que es un error muy habitual). Este problema viene dado porque javascript no es un lenguaje orientado a este tipo de funciones, pero siempre podemos encontrarle solución, en los próximos post veremos como podemos solucionar esto de muchas maneras, mientras tando plantear vosotros posibles soluciones. Nos vemos en el siguiente un abrazoooooor"}]},{"type":"text","value":"\n"},{"type":"comment","value":"kg-card-end: markdown"}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"recursividad","heading":"Recursividad"}]},"featureImageSharp":{"base":"unordered-3192273_640-2.png","publicURL":"/static/e92df4805fb46ec1f6bec181d2305365/unordered-3192273_640-2.png","imageMeta":{"width":640,"height":512},"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFG0lEQVQ4ywEQBe/6APG/tx3SpZ5Y2+PkQNzf3UjCw89E2M6jZubUibvJxK5Yk5/RHmd0qxNMWpUXsLO/LLe5xT+corsvv7++MmxsaxaZmYUXj4+WHsrKyjrNzc1HANSJfnXTZVT/1X5wp7K+vUSttMg40cSUb+zYh97by4ie0smidOHVpIbbzpWb7Nybsuvbmrbd0ZKAnp/khImK5tyWltuK4uHGPOXl6E3NyMdIAJFqZDnPkIiCwW5inMx1abl/j3YbtLb/AOjCOwXl1IRn2MmFntzNk5Tw46uQ493CYMS+olvt2X+avrSnpo6R6KCEhNulmZrkhs3SsikAABILAMfLzkae0MIY/6TMANl3X5vGi5ajeYjzhYiH66WJi+eaq7TzQuTZqG3v3I+008OFfpKk8ie0pm0n792VubCzwjPOzcE9hofluLOt43/Ue2F8ANfWxzZsXLEeh5X/UKZvjFq/eo3ml6HgedPLukaUk+KxjIvdlPnhcoXu2pwW6tWCl8/Iq1Lp15Cv5NacgElUgxje2r4yvcLqYZeH0tfZdGPhALu70USCg+mpgobwgoyG49zFeobjqqbhhYCO6YmDh+SynZ3VX+bUg4Dq1oeN7NiHxOjXj8jk0XNXfoaCFL29wE7Lx8dK0eznLZB8yaHSgH3MAJuc5qKGhuCF3tmJGo2S6rLIdnrJpYq+sLCIr8LKrbdquMG3RJuZo0vHu4eC6NeQy9HPwUuJjNporKzXYbuzoTe1uLtHuLe0P9BrY8C/fYF/AI+Q58Kur9NhvLfDQ3+K8pXFeW9m3nJZ2d1mRoLUb1ydv8HBKcPc+Cu1qoeG8+med5KY8HOYl+bKjo3nvwBn/w6J0MgV1nhjuayBsuFPctxCAIqK7qybm8txAAAAAXyG8Im3kraj2nBY0M9vZazlcWFlAAAADkseE59cLiD4TiMHc3570auip+BMkJnslKZ3q5PXYkie0GhZ4bR9ntm4na5oAIeJ4GGOj+7S1dDJTqe951G3e5nrx2pZTs2/pT+ZjH9IUSohtkYkGP9XJBf/WCIR/1gwNfV2ds+lv3SH1M97csHfiWiGynJ1za10ncfifGW3AOvajLKkn8qdgYLtx7LA8WbegnGkmn2+vJKn/39iRVHMXjcn/z87N/l/ZFP7OSol/0MsHrvEbG2usHef4ouY+aGJnvF1rn+ozdF3ccLMeGqWAOzZjN7444OryLyvuH2K+8C8iZ/U1IJ2oG+u/zB5ZHl8iHBd/6eWifvKqI3/npGF/ZR5bf/EbW3an7DGK6Sl5YuLiuf/jZb2obahhjO1vMJGAPLflS795oUW9+N/ld/QjMXYyJr43I1t9MdNJzUAOAADpodx58Gfh/+2pJbpw6GH+qSGc9rPblisqpfDcKWj1N7m2KHVo57Myri4vFCtpqwTAP///wA4Qu8NgYTuetbLs6rk1pb/ybOjt9VvZ6nCe3R8vZ6Dvph6YsCjhXPzi3FcsbWUgL/SalawjoTgrpufzW7YypGa3c+i5uvbk3jw34+GANDPuTesrNtxi4zo4oqN87bDubTD5NiUt9zOonzEh23DnoF+8JF8gsfRpHz/jndr07mIdvXMfGaGn6TvrJiW2L23sMDh18qbg8urAAXq2pGqANDQ0EM2NjUTeHidH5qZlSEABVkJ/+eDL9fJh43Hpn/zn4ym/6Ca0f+tnbD+nYaO/7eXhvmxroxy7N6gf8u/p57XzJ513+DcQ7e3uzE9PDMO7sYRFrnPY/gAAAAASUVORK5CYII=","aspectRatio":1.25,"src":"/static/e92df4805fb46ec1f6bec181d2305365/8bef3/unordered-3192273_640-2.png","srcSet":"/static/e92df4805fb46ec1f6bec181d2305365/847ef/unordered-3192273_640-2.png 175w,\n/static/e92df4805fb46ec1f6bec181d2305365/91cba/unordered-3192273_640-2.png 350w,\n/static/e92df4805fb46ec1f6bec181d2305365/8bef3/unordered-3192273_640-2.png 640w","srcWebp":"/static/e92df4805fb46ec1f6bec181d2305365/1ea2e/unordered-3192273_640-2.webp","srcSetWebp":"/static/e92df4805fb46ec1f6bec181d2305365/9fca7/unordered-3192273_640-2.webp 175w,\n/static/e92df4805fb46ec1f6bec181d2305365/37a4e/unordered-3192273_640-2.webp 350w,\n/static/e92df4805fb46ec1f6bec181d2305365/1ea2e/unordered-3192273_640-2.webp 640w","sizes":"(max-width: 640px) 100vw, 640px"}}}}}]}},"pageContext":{"slug":"js-algoritmos-y-estructuras-de-datos-big-o","prev":"js-algorithms-and-data-structures","next":"docker-iv-development-workflow","tag":"algoritmos","limit":3,"skip":0,"primaryTagCount":7,"collectionPaths":{}}},
    "staticQueryHashes": ["1272700106","1676991999","2138873178","2546165603","2681841279","2938721187","293880488","3052966952","4156497161"]}