JS - 创建一个回调函数,接受调用它的函数返回的对象

JS - Create a callback function that accepts an object returned by the function invoking it

我从这个数据集开始:

var wide_array = [
  {
    "record": 1,
    "associated_location": "Kirrawee",
    "identity": "student",
    "second_identity": "visitor"
  },
  {
    "record": 2,
    "associated_location": "Sutherland",
    "identity": "student",
    "second_identity": "resident"
  },
  {
    "record": 3,
    "associated_location": "Kirrawee",
    "identity": "visitor",
    "second_identity": "worker"
  },
  {
    "record": 4,
    "associated_location": "Miranda",
    "identity": "resident",
    "second_identity": "worker"
  },
  {
    "record": 5,
    "associated_location": "Miranda",
    "identity": "student",
    "second_identity": ""
  },
  {
    "record": 6,
    "associated_location": "Miranda",
    "identity": "worker",
    "second_identity": "resident"
  },
  {
    "record": 7,
    "associated_location": "Sutherland",
    "identity": "worker",
    "second_identity": "resident"
  }
]; 

    

然后我想将它从 'wide' 格式转换为 'long',我可以通过以下方式完成:

function processData(wide_array) {
  const long_array = [];
  for (let i = 0; i < wide_array.length; i++) {
    const record = wide_array[i];

    // Add "identity"
    long_array.push({ record: record.record, location: record.associated_location, identity_long: record.identity });

    // Add "second_identity"
    long_array.push({ record: record.record, location: record.associated_location, identity_long: record.second_identity });
  }
  return long_array;
}

这给了我:

long_array =    
[
    {"record":1,"location":"Kirrawee","identity_long":"student"},
    {"record":1,"location":"Kirrawee","identity_long":"visitor"},
    {"record":2,"location":"Sutherland","identity_long":"student"},
    {"record":2,"location":"Sutherland","identity_long":"resident"},
    {"record":3,"location":"Kirrawee","identity_long":"visitor"},
    {"record":3,"location":"Kirrawee","identity_long":"worker"},
    {"record":4,"location":"Miranda","identity_long":"resident"},
    {"record":4,"location":"Miranda","identity_long":"worker"},
    {"record":5,"location":"Miranda","identity_long":"student"},
    {"record":5,"location":"Miranda","identity_long":""},
    {"record":6,"location":"Miranda","identity_long":"worker"},
    {"record":6,"location":"Miranda","identity_long":"resident"},
    {"record":7,"location":"Sutherland","identity_long":"worker"},
    {"record":7,"location":"Sutherland","identity_long":"resident"}
];

我想将 processData 创建的 long_array 对象异步传递给以下 addItemCounts 函数:

groupByKeys = ['location', 'identity'];

  function addItemCounts(long_array, groupByKeys) {
  var groups = _.groupBy(long_array, obj => {
    return groupByKeys.map(key => obj[key]).join('-');
  });

  return _.map(groups, g => ({
    ...g[0],
    count: g.length
  }));
}

grouped_and_counted = addItemCounts(long_array, groupByKeys);

哪个returns:

grouped_and_counted = [
  {
    "location": "Kirrawee",
    "identity_long": "student",
    "count": 1
  },
  {
    "location": "Kirrawee",
    "identity_long": "visitor",
    "count": 2
  },
  {
    "location": "Kirrawee",
    "identity_long": "worker",
    "count": 1
  },
  {
    "location": "Sutherland",
    "identity_long": "student",
    "count": 1
  },
  {
    "location": "Sutherland",
    "identity_long": "resident",
    "count": 2
  },
  {
    "location": "Sutherland",
    "identity_long": "worker",
    "count": 1
  },
  {
    "location": "Miranda",
    "identity_long": "resident",
    "count": 2
  },
  {
    "location": "Miranda",
    "identity_long": "worker",
    "count": 2
  },
  {
    "location": "Miranda",
    "identity_long": "student",
    "count": 1
  },
  {
    "location": "Miranda",
    "identity_long": "",
    "count": 1
  }
];

我的问题是,如何重写 processData 函数以将 addItemCounts 作为回调,它接受 processData 返回的输出和一个数组(groupByKeys) 作为参数?

在同步上下文中,我会像这样实现我想要的:

// Step one:
intermediary_object = processData(input);

// Step two:
output_object = addItemCounts(intermediary_object, ['location', 'identity']);

但是这不会异步工作,所以我需要重写processData以将addItemCounts作为异步执行的回调函数。

异步的,我想做的看起来更像下面的伪代码:

processData(wide_array, function(long_array, /* returned by processData */
                                 groupByKeys)) /* ... etc */

您可以重写 processData 以接受函数 addItemCounts 作为第二个参数,如下所示:

processData(wide_array, addItemsCounts); 

在形成 long_array 之后从正文中调用 addItemsCounts(long_array, groupByKeys)

groupByKey 也可以作为 processData 的参数,如果您是从不同的上下文创建的。

最终代码

groupByKeys = ['location', 'identity_long'];

function addItemCounts(long_array, groupByKeys) {
    var groups = _.groupBy(long_array, obj => {
        return groupByKeys.map(key => obj[key]).join('-');
    });
    
    return _.map(groups, g => ({
        ...g[0],
        count: g.length
    }));
}
function processData(wide_array, addItemsCounts, groupByKeys) {
    const long_array = [];
    for (let i = 0; i < wide_array.length; i++) {
        const record = wide_array[i];
    
        // Add "identity"
        long_array.push({ record: record.record, location: record.associated_location, identity_long: record.identity });
    
        // Add "second_identity"
        long_array.push({ record: record.record, location: record.associated_location, identity_long: record.second_identity });
    }
    return addItemsCounts(long_array, groupByKeys);
}

这是大多数接受回调参数的函数的工作方式。

编辑:已添加 jsfiddle