【问题标题】:Using Bluebird Promise in For Loop to build and return an Array of Objects在 For 循环中使用 Bluebird Promise 构建并返回一个对象数组
【发布时间】:2018-01-04 01:37:35
【问题描述】:

我正在尝试使用 Bluebird Promises 构建和返回一个对象。 Promise 是一个 HTTP 请求,它获取附加数据以添加到对象。

我创建了一个在 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;
  });
};

我不知道如何从嵌套的 Promise 中返回值

【问题讨论】:

    标签: javascript promise bluebird zapier-cli


    【解决方案1】:

    您可以使用Promise.reduce 将您在for 循环中创建的promise 列表减少为一个promise:

    ...
        .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.reduce 的返回承诺。

    【讨论】:

      猜你喜欢
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-15
      • 1970-01-01
      • 2019-03-09
      • 2018-05-09
      • 1970-01-01
      相关资源
      最近更新 更多