L’enfer des callbacks

Click here to load reader

  • date post

    15-Apr-2017
  • Category

    Engineering

  • view

    314
  • download

    0

Embed Size (px)

Transcript of L’enfer des callbacks

  • Lenfer des callbacksUn cas dtude en *(Node)JS

    Aurlien Bourdon@aurelienbourdon

  • describe('.totalValue', function() {

    it('should calculate the total value of items in a space', function(done) {

    var table = new Item('table', 'dining room', '07/23/2014', '1', '3000');

    var chair = new Item('chair', 'living room', '07/23/2014', '3', '300');

    var couch = new Item('couch', 'living room', '07/23/2014', '2', '1100');

    var chair2 = new Item('chair', 'living room', '07/23/2014', '4', '500');

    var bed = new Item('bed', 'dining room', '07/23/2014', '1', '2000');

    table.save(function() {

    chair.save(function() {

    couch.save(function() {

    chair2.save(function() {

    bed.save(function() {

    Item.totalValue({room: 'dining room'}, function(totalValue) {

    expect(totalValue).to.equal(5000); done();

    });

    });

    });

    });

    });

    });

    });

    });Sources

    http://thecodebarbarian.com/2015/03/20/callback-hell-is-a-mythhttps://atdreamstate.wordpress.com/2014/12/26/hell-hellfire/

  • Pourquoi est-ce lenfer ?

  • Pourquoi est-ce lenfer ?

    Lecture en cascade

  • Pourquoi est-ce lenfer ?

    Lecture en cascade

    Absence de description fonctionnelle

  • Pourquoi est-ce lenfer ?

    Lecture en cascade

    Couplage fort entre les fonctions

    Absence de description fonctionnelle

  • Pourquoi est-ce lenfer ?

    Lecture en cascade

    Lisibilit hardue

    Maintenance difficile

    Sourcehttp://memesvault.com/sad-meme-face/

    Absence de description fonctionnelle

    Couplage fort entre les fonctions

  • Cas dtude

  • function parseCurrentDir() {

    fs.readdir('.', function (err, files) {

    if (err) {

    console.error(err);

    } else {

    files.forEach(function (file) {

    fs.readFile(file, 'utf8', function (err, content) {

    if (err) {

    console.error(err);

    } else {

    console.log(content);

    }

    });

    });

    }

    });

    }

  • #1 Modularisation

  • Modularisation ?

    Nommage et externalisation des fonctions

  • function parseCurrentDir() {

    fs.readdir('.', function (err, files) {

    if (err) {

    console.error(err);

    } else {

    files.forEach(function (file) {

    fs.readFile(file, 'utf8', function (err, content) {

    if (err) {

    console.error(err);

    } else {

    console.log(content);

    }

    });

    });

    }

    });

    }

  • function parseCurrentDir() {

    fs.readdir('.', function readFiles(err, files) {

    if (err) {

    console.error(err);

    } else {

    files.forEach(function readFile(file) {

    fs.readFile(file, 'utf8', function printContent(err, content) {

    if (err) {

    console.error(err);

    } else {

    console.log(content);

    }

    });

    });

    }

    });

    }

  • function readFile(file) {

    fs.readFile(file, 'utf8', printContent);

    }

    function printContent(err, content) {

    if (err) {

    console.error(err);

    } else {

    console.log(content);

    }

    }

    function parseCurrentDir() {

    fs.readdir('.', readFiles);

    }

    function readFiles(err, files) {

    if (err) {

    console.error(err);

    } else {

    files.forEach(readFile);

    }

    }

  • function readFile(file) {

    fs.readFile(file, 'utf8', printContent);

    }

    function printContent(err, content) {

    if (err) {

    console.error(err);

    } else {

    console.log(content);

    }

    }

    function parseCurrentDir() {

    fs.readdir('.', readFiles);

    }

    function readFiles(err, files) {

    if (err) {

    console.error(err);

    } else {

    files.forEach(readFile);

    }

    }

  • #2 Dcouplage

  • Dcouplage ?

    Sparation des traitements du flow dexcution

  • Dcouplage ?

    Sparation des traitements du flow dexcution

    En utilisant des promises :-)

  • Promises ?

    Abstraction servant de proxy pour un rsultat non-connu au moment o il est rfrenc pour la

    premire fois, car son calcul ou son obtention se feront plus tard lexcution

    - Wikipdia

  • Promises !

    (...)

  • (...)

    Promises !

    https://github.com/kriskowal/q

  • function parseCurrentDir() {

    fs.readdir('.', readFiles);

    }

  • function parseCurrentDir() {

    fs.readdir('.', function (err, files) {

    });

    }

  • function parseCurrentDir() {

    fs.readdir('.', function (err, files) {

    });

    }

  • function parseCurrentDir() {

    Q.Promise(function (resolve, reject, notify) {

    fs.readdir('.', function (err, files) {

    });

    });

    }

  • function parseCurrentDir() {

    Q.Promise(function (resolve, reject, notify) {

    fs.readdir('.', function (err, files) {

    if (err) {

    reject(err);

    } else {

    resolve(files);

    }

    });

    });

    }

  • function parseCurrentDir() {

    return Q.Promise(function (resolve, reject, notify) {

    fs.readdir('.', function (err, files) {

    if (err) {

    reject(err);

    } else {

    resolve(files);

    }

    });

    });

    }

  • function parseCurrentDir() {

    return Q.Promise(function (resolve, reject, notify) {

    fs.readdir('.', function (err, files) {

    if (err) {

    reject(err);

    } else {

    resolve(files);

    }

    });

    });

    }

    Sparation des traitements du flow dexcution

    readFiles(files);

  • function listCurrentDirFiles() {

    return Q.Promise(function (resolve, reject, notify) {

    fs.readdir('.', function (err, files) {

    if (err) {

    reject(err);

    } else {

    resolve(files);

    }

    });

    });

    }

    Sparation des traitements du flow dexcution

    readFiles(files);

  • Mais comment lier notre fonction avec la suivante ?

  • Mais comment lier notre fonction avec la suivante ?

    En utilisant le chanage de promises !

  • listCurrentDirFiles()

  • listCurrentDirFiles()

    .then(readFiles)

  • listCurrentDirFiles()

    .then(readFiles)

    .then(...)

  • listCurrentDirFiles()

    .then(readFiles)

    .then(...)

    .catch(console.error)

  • listCurrentDirFiles()

    .then(readFiles)

    .then(...)

    .catch(console.error)

    .done()

  • Du coup au final a donne quoi ?

  • function parseCurrentDir() {

    fs.readdir('.', function (err, files) {

    if (err) {

    console.error(err);

    } else {

    files.forEach(function (file) {

    fs.readFile(file, 'utf8', function (err, content) {

    if (err) {

    console.error(err);

    } else {

    console.log(content);

    }

    });

    });

    }

    });

    }

  • function parseCurrentDir() {

    listCurrentDirFiles()

    .then(readFiles)

    .then(printContents)

    .catch(console.error)

    .done();

    }

  • function readFile(file) {

    return Q.Promise(function (resolve, reject) {

    fs.readFile(file, 'utf8', function (err, content) {

    if (err) {

    reject(err);

    } else {

    resolve(content);

    }

    });

    });

    }

    function printContents(contents) {

    contents.forEach(function (content) {

    if (content.state === 'fulfilled') {

    console.log(content.value);

    } else {

    console.log('Unable to parse file due to %s', content.reason);

    }

    });

    }

    function listCurrentDirFiles() {

    return Q.Promise(function (resolve, reject) {

    fs.readdir('.', function (err, files) {

    if (err) {

    reject(err);

    } else {

    resolve(files);