Holocron

Navegación

  • Inicio
  • Libros
  • Eventos
  • Seminarios
  • Referencias
  • Contacto
  • Pólitica de privacidad

lunes, 25 de octubre de 2021

Javascript Callbacks

 javascript Callbacks


When processing diferent task that are supposed to be executed in a specific order can be altered when a process take more time to do the job.

var output = '';

function task1(){
    output += 'task1->';
}

function task2(){
    output += 'task2->';
}

function task3(){
    output += 'task3->';
}

task1();
task2();
task3();
console.log(output);

// output: task1->task2->task3->

when task take a little more time to finish each one the console.log(output) is executed before than the tasks.

var output = '';

function task1(){
    setTimeout(() => {
      output += 'task1->';
    }, 0);
}

function task2(){
    setTimeout(() => {
      output += 'task2->';
    }, 0);
}

function task3(){
    setTimeout(() => {
      output += 'task3->';
    }, 0);
}

task1();
task2();
task3();
console.log(output);

// output: <empty string>
 

If the console.log is also executed in a little more time the update of output is perfectly reached.

var output = '';

function task1(){
    setTimeout(() => {
      output += 'task1->';
    }, 0);
}

function task2(){
    setTimeout(() => {
      output += 'task2->';
    }, 0);
}

function task3(){
    setTimeout(() => {
      output += 'task3->';
    }, 0);
}

task1();
task2();
task3();
setTimeout(() => {
  console.log(output);
}, 0);

// output: task1->task2->task3->
 
 In the next case each task take a little more time that his previous one, and the console output only takes the changes till the task2.
 
var output = '';

function task1(){
    setTimeout(() => {
      output += 'task1->';
    }, 10);
}

function task2(){
    setTimeout(() => {
      output += 'task2->';
    }, 20);
}

function task3(){
    setTimeout(() => {
      output += 'task3->';
    }, 30);
}

task1();
task2();
task3();
setTimeout(() => {
  console.log(output);
}, 20);

// output: task1->task2->
 
 But when the time taken for each task is not the same as the supossed order.

var output = '';

function task1(){
    setTimeout(() => {
      output += 'task1->';
    }, 30);
}

function task2(){
    setTimeout(() => {
      output += 'task2->';
    }, 10);
}

function task3(){
    setTimeout(() => {
      output += 'task3->';
    }, 20);
}

task1();
task2();
task3();
setTimeout(() => {
  console.log(output);
}, 30);

// output: task2->task3->task1->
 
To Ensure that the order excecution be the correct, we use callback functions to be executed inside their respective block code of setTimeout, so independently the time it takes to do the task always the task secuence will be in the desired order.
 
var output = '';

function task1(callback){
    setTimeout(() => {
      output += 'task1->';
      callback();
    }, 30);
}

function task2(callback){
    setTimeout(() => {
      output += 'task2->';
      callback();
    }, 10);
}

function task3(callback){
    setTimeout(() => {
      output += 'task3->';
      callback();
    }, 20);
}

task1( () => {
     task2( () => {
         task3( ()=>{}
         )
     })
});

setTimeout(() => {
  console.log(output);
}, 100);

// output: task1->task2->task3->
 
Another way to do call the callback, notice the output timeout more than the sum of the timeout of the task to catch all the changes.
 
var output = '';

function task1(fn){
    setTimeout(() => {
      fn('task1->');
    }, 30);
}

function task2(fn){
    setTimeout(() => {
      fn('task2->');
    }, 10);
}

function task3(fn){
    setTimeout(() => {
      fn('task3->');
    }, 20);
}

task1( m => {
    output += m;
    task2( m2 => {
        output += m2;
        task3( m3 => {
            output += m3;
        })
    })
});

setTimeout(() => {
  console.log(output);
}, 70);

// output: task1->task2->task3->
 
 
The same mechanism is used here to asure the correct order
 
const posts = [{title: 'post one', body: 'body of post one'},
              {title: 'post two', body: 'body of post two'}];

function getPosts(){
    setTimeout(() => {
      let output = '';
      posts.forEach( (post, index) => {
        console.log(index + ' ' + post.title );
        output += `<li>${post.title}</li>`;
      });
      document.body.innerHTML = output;}
    ,1000);
};

function createPost(post, callback){
   setTimeout(() => {
       posts.push(post);
       callback();
   },2000);
   
};

createPost({title: 'post three', body:'body of post three'}, getPosts);
 
 Browser output:

  • post one
  • post two
  • post three
  •  
     Another example of callbacks with files
     
    first the file basic
    readfile.js
    //readfile.js 
    var fs = require('fs')

    function getRecord( filepath, done){
        fs.readFile(filepath, function(err, data) {
            if (err) return done(err)

            data = data.toString().split('\r\n')
            console.log(data)
        })
    }

    getRecord('personas.txt')
      
     
    To run this script, in the console type
    >node readfile.js
     
    > node readfiles.js
    [
      'Juan Perez',
      'Luis Rogriguez',
      'Karla Martinez',
      'Luisa Miranda',
      'Manuel Lopez',
      'Jose Alberto'
    ]
     
    Now using callback
     
    file personas.estudiantes
    Luis Rogriguez
    Luisa Miranda
    Jose Alberto
     
    file personas.txt
    Juan Perez
    Luis Rogriguez
    Karla Martinez
    Luisa Miranda
    Manuel Lopez
    Jose Alberto
     
    //index.js 
    var fs = require('fs')

    function getPersonsStudents( filepath, done){
        fs.readFile(filepath, function(err, persons){
            if(err) return done(err)

            fs.readFile('personas.estudiantes', function(err, students){
                if(err) return done(err)

                groupIntersection(persons, students)
            })
        })

        function groupIntersection( persons, students){
            students = students.toString().split('\r\n');
            persons = persons.toString().split('\r\n').filter(function(person){
                return students.indexOf(person) !== -1
            })
            done(null, persons)
        }
    }

    getPersonsStudents('personas.txt', function(err, person){
        console.log(person);
    })
     
    To run the script type
    >node index.js
     
    [ 'Luis Rogriguez', 'Luisa Miranda', 'Jose Alberto' ]
     
     Another Sample, loading the following images in order are not guarantee


    var persons = ['Jose Alberto','elena jimenez','Luisa Miranda']
    var count = persons.length

    persons = persons.map(function(person){
        var img = new Image()
        img.onload = function() {
            next()
        }
        img.src = person + '.jpg'
        return img
    })

    function next() {
        count--

        if (count < 1){
            persons.forEach( function(person) {
                console.log(person.width)
                document.body.appendChild(person)
            })
        }
    }

     
     In this version the order is preserved on load by using recursivity.
     
    var persons = ['Jose Alberto','elena jimenez','Luisa Miranda']
    var images = []

    function loadImages(){
        var person = persons.shift()
        if(!person){
            console.log('All images loaded.', images)
            return
        }
        var img = new Image()
        img.onload = function(){
            loadImages()
        }
        img.src = person + '.jpg'
        images.push(img)
    }

    loadImages()
     
     
    browser inspector output:
     All images loaded.
    Array(3) [ img, img, img ]
    ​0: <img src="Jose Alberto.jpg">
    ​1: <img src="elena jimenez.jpg">
    ​2: <img src="Luisa Miranda.jpg">
    ​length: 3
    ​
     

     
     
    eot
    Publicado por José Alberto Martínez Rodríguez en 16:56
    Enviar por correo electrónicoEscribe un blogCompartir en XCompartir con FacebookCompartir en Pinterest

    No hay comentarios:

    Publicar un comentario

    Entrada más reciente Entrada antigua Inicio
    Suscribirse a: Enviar comentarios (Atom)

    Proto Paginas Web

    • Página principal
    • Proto WebResponsive
    • Proto página UNC
    • Proto MVC PHP AJAX Backend
    • Proto AngularJS Lab
    • Proto AgencyPage
    • TheArt&ScienceCSSPractice

    Enlaces Bibliográficos

    • Libros
    • Yahoo yui
    • Yahoo query language
    • s1mp3

    Archivo del blog

    • ►  2023 (2)
      • ►  septiembre (1)
      • ►  abril (1)
    • ►  2022 (33)
      • ►  noviembre (2)
      • ►  octubre (1)
      • ►  julio (1)
      • ►  junio (5)
      • ►  mayo (3)
      • ►  marzo (10)
      • ►  febrero (1)
      • ►  enero (10)
    • ▼  2021 (40)
      • ►  diciembre (2)
      • ►  noviembre (1)
      • ▼  octubre (9)
        • Java Servlet Filters
        • Javascript async/await
        • Javascript Promises
        • Javascript Callbacks
        • React Tic-Tac-Toc exercice with Extras
        • React, pass data from Child to Parent, Parent to C...
        • React Hook useReducer
        • React Hook useEffect
        • React Hooks useState
      • ►  septiembre (15)
      • ►  agosto (11)
      • ►  junio (2)
    • ►  2020 (21)
      • ►  diciembre (11)
      • ►  noviembre (8)
      • ►  octubre (1)
      • ►  septiembre (1)
    • ►  2019 (133)
      • ►  diciembre (7)
      • ►  noviembre (19)
      • ►  octubre (12)
      • ►  septiembre (21)
      • ►  agosto (14)
      • ►  julio (34)
      • ►  junio (26)
    • ►  2018 (29)
      • ►  diciembre (2)
      • ►  mayo (4)
      • ►  abril (6)
      • ►  marzo (12)
      • ►  febrero (3)
      • ►  enero (2)
    • ►  2017 (45)
      • ►  diciembre (1)
      • ►  noviembre (12)
      • ►  octubre (12)
      • ►  septiembre (1)
      • ►  agosto (5)
      • ►  julio (2)
      • ►  junio (6)
      • ►  mayo (4)
      • ►  abril (2)
    • ►  2016 (50)
      • ►  diciembre (2)
      • ►  noviembre (1)
      • ►  octubre (2)
      • ►  junio (6)
      • ►  mayo (11)
      • ►  abril (7)
      • ►  marzo (9)
      • ►  febrero (11)
      • ►  enero (1)
    • ►  2015 (1)
      • ►  mayo (1)
    • ►  2014 (5)
      • ►  octubre (1)
      • ►  agosto (2)
      • ►  abril (1)
      • ►  marzo (1)
    Tema Sencillo. Con la tecnología de Blogger.