Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > JavaScript, DOM/DHTML >  Async function  callback hell


Автор: Cfon 30.09.18, 08:32
Запутался я... ад колбэков в действии! :D
Не могу понять куда вставить count++, чтобы выводилось сообщение completed!
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    'use strict';
     
    const fs = require('fs');
    const ws = fs.createWriteStream('./app.log', {
      flags: 'a',
      encoding: 'utf8',
      mode: 0o666
    });
    const dir = './data/';
     
    ws.on('open', () => {
      var count = 0;
      
      fs.readdir(dir, (err, files) => {
        if (err) return console.error(err.message);
     
        files.forEach(fname => {
          count++; //<--- тут не катит
     
          fs.readFile(dir + fname, 'utf8', (err, data) => {
            if (err) return console.error(err.message);
     
            if (data.match(/microsoft\.com/g) !== null) {
              var changed = data.replace(/microsoft\.com/g, 'mudosoft.com');
     
              fs.writeFile(dir + fname, changed, err => {
                if (err) return console.error(err.message);
     
                ws.write('changed '+ fname +'\n', 'utf8', err => {
                  if (err) return console.error(err.message);
     
                  if (count >= files.length) { //<-- ???
                    console.log('completed.');
                  }
                });
              });
            }
          });
        });
      });
    });
     
    ws.on('error', err => {
      console.error('Error:' + err);
    });

Автор: Cfon 30.09.18, 12:01
Сам все порешал :D
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    ws.on('open', () => {
      fs.readdir(dir, (err, files) => {
        if (err) return console.error(err.message);
        var count = 0,  //<--- текущее изменение
            totalСhanges = 0; //<--- общее число изменений
     
        files.forEach(fname => {
          fs.readFile(dir + fname, 'utf8', (err, data) => {
            if (err) return console.error(err.message);
     
            if (data.match(/microsoft\.com/g) !== null) {
              var changed = data.replace(/microsoft\.com/g, 'mudosoft.com');
              totalСhanges++; //<--- тут подсчитываем
     
              fs.writeFile(dir + fname, changed, err => {
                if (err) return console.error(err.message);
     
                ws.write('changed '+ fname +'\n', 'utf8', err => {
                  if (err) return console.error(err.message);
                  
                  console.log('changed');
                  count++; //<--- и тут подсчитываем
     
                  if (count ===  totalСhanges) { //<--- проверка
                    console.log('all completed.');
                  }
                });
              });
            }
          });
        });
      });
    });

Короче ввел еще одну переменную totalChanges и заработало!
Проблема была разобраться где тут синхронный а где асинхронный код :wacko:
"Ад колбэков" реально запутал!
Надо было сделать через промисы и не париться :D

Автор: Cfon 30.09.18, 18:04
Заюзал промисы и async/await! Теперь дополнительная переменная totalChanges не нужна :D
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    const promisify = require('util').promisify;
     
    // промосификация
    const readdir = promisify(fs.readdir);
    const readFile = promisify(fs.readFile);
    const writeFile = promisify(fs.writeFile);
     
    ws.on('open', () => {
      readdir(dir).then(files => {
        var count = 0;
     
        files.forEach(fname => {
          readFile(dir + fname, 'utf8').then(async data => {
            if (data.search(/microsoft\.com/g) !== -1) {
              var changedData = data.replace(/microsoft\.com/g, 'mudosoft.com');
              await writeFile(dir + fname, changedData);
              ws.write('changed '+ fname +'\n', 'utf8');
              console.log('changed ' + fname);
            }
            if (++count >= files.length) {
              console.log('all completed.');
            }
          })
          .catch(err => console.error(err.message));
        });
      })
      .catch(err => console.error(err.message));
    });

Код стал более простым согласитесь :D

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)