2014-11-08 3 views
1

У меня есть приложение, в котором я использовал async, чтобы избежать «обратного вызова спагетти» и работал правильно, но в некоторых параллельных вызовах мне пришлось внести некоторые изменения, потому что значения должны быть изменены перед возвратом, так как эти изменения сделал ту же рутину, что и я думал, чтобы сделать функцию для этого и, таким образом, сохранить код, но не работает приложение (Я новичок в javascript, и я учусь).Javascript async callback hell

Отладка (console.log), ошибка в некоторых случаях - это тот же обратный вызов, что он вызывается из разных запросов (если они локальные переменные не понимают, как это происходит). Я попытался изменить код с помощью forEach и async.each, но в обоих случаях у меня есть ошибки и больше не так много изменений, чтобы продолжать попытки, не могу найти ошибку.

Мой исходный код (я описываю это, чтобы избежать длинный пост):

async.parallel({ 
    today: function(callback){ 

     data.get('DATA', function(err, dataGet){ 

      if(err){ 
       callback(err); 
      } 
      callback(null, dataGet); 
     }); 
    }, 
    .... yesteday, week, month .... 
    year: function(callback){ 

     data.get('DATA', function(err, dataGet){ 

      if(err){ 
       callback(err); 
      } 
      callback(null, dataGet); 
     }); 
    } 
}, 
function(error, results){ 
    --- routine ---- 
}); 

И мой новый код это:

Функция

function getDataChange(key, valuePass, callback){ 

    var values = [ .... ], 
     totalData = 0.00; 

    /* 
    async.each(values, function(value, cb){ 

     var keyR = key.replace(/%value%/g, value.toLowerCase()); 

     data.get(keyR, function(err, dataGet){ 

      if(err){ 
       cb(err); 
      } 

      dataGet = (dataGet !== null) ? dataGet : 0 ; 

      if(valuePass === value) { 

       totalData += parseFloat(dataGet); 
       cb(); 

      } else { 

       valueConverter.convert({ force: true, multi: true }, function(data){ 

        totalData += parseFloat(data); 
        cb(); 
       }); 
      } 
     }); 
    }, 
    function(err){ 

     if(err){ 
      callback(err); 
     } else { 
      callback(null, totalData); 
     } 
    }); 
    */ 

    var totals = values.length; 

    values.forEach(function(value){ 

     var keyR = key.replace(/%value%/g, value.toLowerCase()); 

     data.get(keyR, function(err, dataGet){ 

      if(err){ 
       return callback(err); 
      } 
      dataGet = (dataGet !== null) ? dataGet : 0 ; 
      total--; 

      if(valuePass === value) { 

       totalData += parseFloat(dataGet); 

       if(totals === 0){  
        callback(null, totalData); 
       } 
      } else { 

       valueConverter.convert({ force: true, multi: true }, function(data){ 

        totalData += parseFloat(data); 

        if(totals === 0){ 
         callback(null, totalData); 
        } 
       }); 
      } 
     }); 
    }); 
    //callback(null, totalData); 
} 

И изменяет основную процедуру е:

var keyBase = '......', 
    value = '.....'; 

async.parallel({ 

    today: function(callback){ 
     /* 
     data.get('DATA', function(err, dataGet){ 

      if(err){ 
       callback(err); 
      } 
      callback(null, dataGet); 
     }); 
     */ 
     getDataChange(keyBase + 'DATAD', value, function(err, returnData){ 

      if(err){ 
       callback(err); 
      } 
      //console.log('## Return Data today'); 
      callback(null, returnData); 
     }); 
     //callback(null, 0); 
    }, 
    .... yesteday, week, month .... 
    year: function(callback){ 

     getDataChange(keyBase + 'DATAY', value, function(err, returnData){ 

      if(err){ 
       callback(err); 
      } 
      console.log('## Return Data year'); 
      callback(null, returnData); 
     }); 
    } 
}, 
function(error, results){ 
    --- routine ---- 
}); 

Я думаю, что я должен буду дублировать код внедряя в параллельных асинхронных вызовов, так как я не в состоянии работать.

Мои ошибки различны. В различных тестах я прокомментировал вызов функции, и я установил возвращаемое из обратного вызова значение 0 в нескольких параллельных вызовах, и я видел, что не работает конечная функция обратного вызова async.parallel (например, если я прокомментировал все вызовы, кроме сегодня, вчера и неделю). В других случаях (установка всех вызовов в качестве комментария и установка значения обратно на 0, кроме вчера и недели), выполняется двухнедельный обратный вызов. Если все вызовы функции комментируются, за исключением недели и сегодня, это вызывает исключение, отображающее сообщение «Ошибка: обратный звонок уже был вызван».

Я застрял в течение нескольких дней и не могу найти ошибку или как решить эту проблему: -S

Спасибо вам.

+0

Если я изменяю содержимое значений массива (var values ​​= [....]) и содержащий один элемент, он корректно работает в версии async.each. Я не понимаю, что происходит. – Anto

ответ

2

Исправлено!

Один из модулей, которые использовали функцию, назывался запросом на веб-api, с большой задержкой ответа.