2017-07-28 88 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的退貨承諾。