2015-09-30 2 views
4

Вот мой горячий беспорядок функции. Это будет захватывать варианты модели (которые находятся в массиве как строки) из файла csv (путь к этому файлу зависит от текста, который мы извлекаем из других файлов csv, и, следовательно, цикла).Как изменить обещания в вложенных циклах?

csvService.getCsvAsArray вызов, который вы видите, получает объект с содержимым файла csv, где каждый столбец хранится в массиве под атрибутом с именем верхнего столбца. Это прекрасно работает, поэтому просто знайте, что когда вы видите такие вещи, как result["NavigationSectionShortNames"], это всего лишь массив строк.

var INDEX_OF_PRODUCTS_SECTION = 1; 
    var getAllModelVariants = function() { 
     return csvService.getCsvAsArray("Contents/Sections/" + navFileNames[INDEX_OF_PRODUCTS_SECTION] + "/order.csv").then(function (result) { 
      var products = []; 
      for (var i = 0; i < result["NavigationSectionShortNames"].length; i++) { 
       csvService.getCsvAsArray("Contents/Sections/" + navFileNames[INDEX_OF_PRODUCTS_SECTION] + "/" + result["NavigationSectionShortNames"][i] 
       + "/order.csv").then(function (productModelInfo) { 
        var productFamilies = []; //array of all different families for a certain product 
        for (var j = 0; j < productModelInfo["NavigationSectionShortNames"].length; j++) { 
         csvService.getCsvAsArray("Contents/Sections/" + navFileNames[INDEX_OF_PRODUCTS_SECTION].length + "/" + result["NavigationSectionShortNames"][i] + "/" + productModelInfo["NavigationSectionShortNames"][j] + "/order.csv").then(function (modelVariants) { 
          var productModels = []; //array of all different model types for a certain family 
          for (var k = 0; k < modelVariants.length; k++) { 
           productModels.push(modelVariants["NavigationSections"][k]); 
          }; 
          productFamilies.push(productModels); 
         }); 
        }; 
        products.push(productFamilies); 
       }); 

      }; 
     }) 
     return products; 
    }; 

Очевидно, что это не будет работать, потому что к тому времени, когда обещание не будет решено, приращение переменного (I, J, или к) уже изменился. Нужно ли использовать обещания для вложенных циклов, подобных этим? Я наткнулся на $q.all, но я изо всех сил пытаюсь понять, как применить его к моей функции. В настоящее время я смотрю this example, который использует обещания в одиночном цикле, и я попытаюсь расширить его.

Мое желание вернуть 3D-массив (см., Например, plunker внизу вопроса).

Если это помогает, вот это упрощенная версия этой функции со статическими данными и не обещает:

var getAllModelVariantsTest = function() { 
     var result = ["productFamily1", "productFamily2", "productFamily3"]; 
     var testArray = ["productFamilyModel1", "productFamilyModelt2", "productFamilyModel3", "productFamilyModel4"]; 
     var testArray3 = ["productFamilyModelVariant1", "productFamilyModelVariant2", "productFamilyModelVariant3", "productFamilyModelVariant4"]; 
      var products = []; 
      for (var i = 0; i < result.length; i++) { 
        var productFamilies = []; //array of all different families for a certain product 
        for (var j = 0; j < testArray.length; j++) { 
          var productModels = []; //array of all different model types for a certain family 
          for (var k = 0; k < testArray3.length; k++) { 
           productModels.push(testArray3[k]); 
          }; 
          productFamilies.push(productModels); 
        }; 
       products.push(productFamilies); 
      }; 
      return products; 
    }; 
    var testOutput = getAllModelVariantsTest(); 

Here it is in plunker form

Если вы бежите, что вы можете увидеть пример того, какой вид вывода I Я желаю своей функции выше.

Мне интересно, как я могу получить свою первую функцию с обещаниями в вложенных циклах, чтобы работать как версия в плункере. Есть ли способ сделать это с увеличением счетных переменных и обещаний?

Есть $q.all путь?

Большое спасибо за ваше время. Дайте мне знать, если вам нужно что-нибудь еще, или если я неясен.

+1

Да, $ q.all - это путь – sirrocco

+1

$ q.all + Array.prototype.map – Evgeniy

ответ

2

Ответный Ад или Пирамида решения судьбы:

function fatchAllDataForProduct(product) { 

    var getProductFamilies = (product) => Promise.resolve(["productFamily1", "productFamily2", "productFamily3"]); 
    var getFamilyModels = (productFamily) => Promise.resolve(["productFamilyModel1", "productFamilyModelt2", "productFamilyModel3", "productFamilyModel4"]); 
    var getModelVariants = (familyModel) => Promise.resolve(["productFamilyModelVariant1", "productFamilyModelVariant2", "productFamilyModelVariant3", "productFamilyModelVariant4"]); 
    var processVariant  = (modelVariant) => modelVariant; 
    var mapFunArray = (fun) => (array) => array.map(fun); // mapFunArray(e => e)([1,2,3,4]) 

    return getProductFamilies(product) 
    .then(pfs => pfs 
     .map(pf => getFamilyModels(pf) 
     .then(fms => fms 
      .map(fm => getModelVariants(fm) 
      .then(mvs => mvs 
       .map(processVariant) 
      ) 
     ) 
     ) 
    ) 
    ); 
} 

fatchAllDataForProduct('foobarProduct').then(
    results => { 
    console.log(results); 
    } 
); 

getFoos возвращается Promise.
Назовем номер then, который возвращает другой номер Promise.
Внутри then мы вызываем foos.map(..getBars().then..), который возвращает массив обещаний.
Внутри then мы звоним bars.map(..getGoos.then..).
Goos обещает в свою очередь решение результатов.

Что Вы получаете (* означает массив):

productPromise: 
    *familyPromise: 
    *modelsPromise: 
     *processedVariant 

Чтобы избавиться от проблемы Ответного ада вы можете использовать async/await особенность EcmaScript7, доступные сегодня с transpilers как Бабель.

async function fatchAllDataForProduct(product) { 

    var getProductFamilies = (product) => Promise.resolve(["productFamily1", "productFamily2", "productFamily3"]); 
    var getFamilyModels = (productFamily) => Promise.resolve(["productFamilyModel1", "productFamilyModelt2", "productFamilyModel3", "productFamilyModel4"]); 
    var getModelVariants = (familyModel) => Promise.resolve(["productFamilyModelVariant1", "productFamilyModelVariant2", "productFamilyModelVariant3", "productFamilyModelVariant4"]); 
    var processVariant  = (modelVariant) => modelVariant; 

    var pfs = await getProductFamilies(product); 
    var promises = pfs.map(async(pf) => { 
    var fms = await getFamilyModels(pf) 
    return fms.map(async(fm) => { 
     var mvs = await getModelVariants(fm); 
     return mvs.map(processVariant) 
    }) 
    }); 
    return Promise.all(promises); 
} 

fatchAllDataForProduct('foobar').then(
    results => { 
    for(var promise of results) { 
     promise.then(...) 
    } 
    } 
); 
+0

Ваша проблема действительно сложная, я предлагаю вам использовать 'Babel' с функциями' async/await' или другими более готовыми к выпуску библиотеками. – ilyaigpetrov

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