2017-07-28 85 views
0

我试图建立和使用蓝鸟承诺返回一个对象的数组。 Promise是一个HTTP请求,它获取要添加到对象的附加数据。在For循环使用蓝鸟承诺建立并返回对象

我创建的执行for循环的请求的功能(我还使用了一个框架,进行一些中间件 - 这是z.是关于什么的)

const getWebAppCustomFieldDetails = (z, url) => { 
    const responsePromise = z.request({ 
     url:url, 
     headers:{ 
      'content-type': 'application/json' 
     } 
    }); 
    return responsePromise 
    .then(response =>{ 
     return JSON.parse(response.content); 
    }); 
}; 

该函数中调用下面的代码:

const webAppFields = (z, bundle) => { 
//This section carries creates an initial request which gets the bulk of the data 
const responsePromise = z.request({ 
    url: webAppUrl(bundle) + '/' + encodeURI(bundle.inputData.webApp), 
    headers:{ 
    'content-type': 'application/json' 
    }, 
}); 
//This is an array to hold the objects created from the response 
var fields = []; 
return responsePromise 
    .then(response => { 

    response = JSON.parse(response.content); 

    //From the response, append the core fields 
    response.systemFields.forEach(function (systemField) { 
     fields.push({ 
     'key': systemField.name, 
     'required': systemField.required, 
     'type': systemField.type.toLowerCase() 
     }); 
    }); 
    return response; 
    }) 
    .then(response => { 
    //Sometimes there are custom fields that need to be retrieved individually 
    const customFieldCount = response.fields.length; 
    var customFieldAppend = ''; 
    for (var i = 0; i < customFieldCount; i++){ 

     getWebAppCustomFieldDetails(z, response.fields[0].links[0].uri) 
     .then(response =>{ 
      customFieldAppend = { 
      'key': response.name, 
      'required': response.required, 
      'type': response.type.toLowerCase() 
      }; 
      //This push doesn't updated the fields array! 
      fields.push(customFieldAppend); 
     }); 
    } 
    //This return does not include the custom fields! 
    return fields; 
    }); 
}; 

我无法弄清楚如何从嵌套承诺返回值

回答

0

您可以使用Promise.reduce减少你所创建的for环路内成一个单一的承诺的承诺清单:

... 
    .then(response => { 
     const customFieldCount = response.fields.length; 
     var customFieldAppend = ''; 

     // Promice.reduce will return the accumulator "totalFields" 
     return Promise.reduce(response.fields, (totalFields, field) => { 
      getWebAppCustomFieldDetails(z, field.links[0].uri) // Using the "field" variable provided by the reducer function 
          .then(response => { 
           customFieldAppend = { 
            'key': response.name, 
            'required': response.required, 
            'type': response.type.toLowerCase() 
           }; 
           // Add the data to the accumulator "totalFields" 
           totalFields.push(customFieldAppend); 
          }); 
     }, []); // The third argument is the initial value of the accummulator. In your example it is a an array, so the initial value is an empty array. 
    }); 
... 

Promise.reduce需要输入三个参数:参数列表循环上(response.fields),该reducer功能和初始累加器的值。蓄能器(我称为totalFields)是reducer函数的第一个参数,它是用来减少在一个单一的值列表中的值的变量。在你的情况累加器是一个数组(该fields阵列中你的实施例中使用),因此它的初始值是一个空数组。

里面的reduce功能,您可以访问列表(第二个参数)的单一元素,你可以打电话给你的异步操作和填充累积广告的每一步。函数Promise.reduce将返回包含在promise中的累加器。因此,您的功能可以直接返回Promise.reduce的退货承诺。