2015-09-30 52 views
4

这是我的一个功能混乱。这将从csv文件中抓取模型变体(它们以字符串的形式存在于数组中)(该文件的路径取决于我们从其他csv文件抓取的文本,因此循环)。如何更改嵌套for循环中的承诺?

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,或K)已经改变了。有没有在这些成功的嵌套for循环中使用promise?我碰到过$q.all,但我正在努力弄清楚如何将它应用于我的功能。我目前正在寻找在单个for循环中使用promises的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

如果你运行,你可以看到什么样的输出我的一个例子我渴望上面的功能。

我想知道如何让我的第一个函数的承诺嵌套for循环工作像在plunker版本。有没有办法做到这一点,增加计数器变量和承诺?

$q.all要走的路吗?

非常感谢您的时间。如果您需要其他任何东西或者我不清楚,请告诉我。

+1

是的,$ q.all是要走的路 – sirrocco

+1

$ q.all + Array.prototype。地图 – 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。我们称之为foos.map(..getBars().then..),它返回承诺数组。
里面then我们叫bars.map(..getGoos.then..)
Goos承诺反过来决心结果。

你得到的是(*意味着数组):

productPromise: 
    *familyPromise: 
    *modelsPromise: 
     *processedVariant 

为了摆脱回调地狱的问题,你可以使用EcmaScript7的async/await功能,可今天与像巴贝尔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

您的问题确实错综复杂,我建议您使用具有'async/await'功能的'Babel'或其他更多生产准备库。 – ilyaigpetrov