2014-12-12 1 views
1

У меня есть следующие функции синхронизации:Преобразование петель в ASync в узле

   for (var i = 0; i < results.length; i++) { 
         var key1 = results[i]['__key']; 
         for (var j = i + 1; j < results.length; j++) { 
          var key2 = results[j]['__key']; 
          if (key1 == key2) { 
           for (var k = 0; k < results[i].length; k++) { 
            for (var z = 0; z < results[j].length; z++) { 
             if (results[i][k][key1] == results[j][z][key2]) { 
              results[i][k] = lodash.extend(results[j][z], results[i][k]); 
              results[j].splice(z, 1); 
             } 
            } 
           } 
          } 
         } 
        } 

Могу ли я изменить все 4 петли на ASync? Я не уверен, можно ли синхронизировать первые две петли! Могу я? Я попытался изменить последние два цикла на асинхронный, но это не дает мне правильный результат? Не могли бы вы помочь мне, как я могу изменить свои циклы синхронизации на асинхронные?

Моя попытка:

   for (var i = 0; i < results.length; i++) { 
       var key1 = results[i]['__key']; 
       for (var j = i + 1; j < results.length; j++) { 
        var key2 = results[j]['__key']; 
        if (key1 == key2) { 
         async.each(results[i], function (resultA, callback) { 

          async.each(results[j], function (resultB, callback) { 
           if (resultA[key1] == resultB[key2]) { 
            resultA = lodash.extend(resultB, resultA); 
            results[j].splice(resultB, 1); 
           } 
           callback(); 
          }, function (err) { 
           callback(err); 
          }), function (err) { 
           callback(err); 
          } 
         }) 
        } 
       } 
      } 

Полный алгоритм:

 async.map(models, getData, function (err, results) { 
      if (err) { 
       res.json(400, err); 
      } else { 

       for (var i = 0; i < results.length; i++) { 
        var key1 = results[i]['__key']; 
        for (var j = i + 1; j < results.length; j++) { 
         var key2 = results[j]['__key']; 
         if (key1 == key2) { 

          for (var k = 0; k < results[i].length; k++) { 
           for (var z = 0; z < results[j].length; z++) { 
            if (results[i][k][key1] == results[j][z][key2]) { 
             results[i][k] = lodash.extend(results[j][z], results[i][k]); 
             results[j].splice(z, 1); 
            } 
           } 
          } 
         } 
        } 
       } 

       var mergedResult = []; 
       mergedResult = mergedResult.concat.apply(mergedResult, results); 
       res.json(200, mergedResult); 
      } 
     }); 


     function getData(model, next) { 
      var data = db.getData(model.type, function (err, data) { 
       data['__key'] = db.getKey(model.type).toString(); 
       next(err, data); 
      }); 
     } 
+2

Смена исходного кода, который вы должны использовать, не собирается покупать вам ничего. Если что-либо, изменение его для async может привести к большей задержке. Просто держи это так, как если бы он уже работал на тебя. – mscdex

+0

, если вы намерены сделать ваш код «плоским», чтобы он не стал http://callbackhell.com/, вы могли бы разбить свои циклы на функции, которые передают параметры между ними по мере необходимости. Это должно помочь с облегчением части углубления/глубокого гнездования, которое у вас есть – haxxxton

+1

В зависимости от того, сколько элементов повторяется, асинхронная покупка будет вам ** ** **. Ничто не блокирует узел, кроме вашего собственного кода. Глубоко вложенные петли, подобные этому, могут блокироваться в течение заметного промежутка времени, и это предотвратит что-либо еще в вашем приложении. –

ответ

0

Я вижу проблемы, основанный на коде. Похоже, вы повторяете массив моделей и захватываете все свои данные на основе типа. Затем вы пытаетесь объединить массивы, если тип один и тот же. Однако db.getData() должен возвращать те же результаты, если вы передаете один и тот же тип, поэтому не должно быть ничего, чтобы слиться позже.

Основываясь на моем понимании вашей проблемы, что-то вроде этого даст вам результаты, которые вы ищете без всякого беспорядка.

var results = {}; 

async.each(models, getData, function(err) { 
    res.json(200, results); 
}); 

function getData(model, next) { 
    var key = db.getKey(model.type).toString(); 

    if(results[key]) { 
    return next(); 
    } 

    db.getData(model.type, function (err, data) { 
    results[key] = data; 
    next(err); 
    }); 
} 

Вы только извлекаете данные из этого model.type, если вы еще не извлекли его. Тогда нечего сливать, и вы можете просто вернуть эти данные.

+0

«Затем вы пытаетесь объединить массивы, если тип тот же». Нет, если они не совпадают с типом! –

+0

Вы получаете ключ для первого сравнения с model.type. 'data ['__ key'] = db.getKey (model.type) .toString();'. –

Смежные вопросы