Skip to content

数据迭代器

什么是数据迭代器

数据迭代器旨在帮助你生成数据时能够按序的使用集合中的数据,简化你代码编写,比如有如下的场景:

需要生成 3 个用户数据,每个用户数据兴趣爱好都不同

如果通过传统faker.js来进行书写将是这样的代码:

javascript
let hobbyArr = ['篮球', '足球', '乒乓球'];
let index = 0;
const userModel = defineModel('user', {
  id: 'string.uuid',
  hobby: () => {
    return hobbyArr[index++];
  },
});
console.log(fakeData(userModel, 4));

生成的数据如下:

json
[
  { "id": "d16e7a49-5e7a-40a0-97e7-68693ffa7268", "hobby": "篮球" },
  { "id": "268a6a63-5eee-4668-a166-d1b9f8bcf510", "hobby": "足球" },
  { "id": "2ed907c6-0cdf-40bd-95cf-6aaf3ebe5d1c", "hobby": "乒乓球" },
  { "id": "7d9b0df7-7fd3-401d-a7a9-59759a0948b4", "hobby": undefined }
]

可以看到你需要手动维护index变量,这并不方便而且容易与其它index变量进行混淆,所以DataFaker考虑到了这种情况,你只需要获取一个迭代器,就可以按序的使用集合中的数据。如下所示:

javascript
let hobbyArr = ['篮球', '足球', '乒乓球'];
const iterator = IteratorFactory.getIterator(hobbyArr);
const userModel = defineModel('user', {
  id: 'string.uuid',
  hobby: () => {
    return iterator.next().value;
  },
});
console.log(fakeData(userModel, 4));

四种数据迭代器

DataFaker提供了四种数据迭代器,这些迭代器可以从迭代器工厂IteratorFactory中获取,分别是:

  • 正向迭代器 :IteratorFactory.getIterator()
  • 逆向迭代器:IteratorFactory.getReverseIterator()
  • 循环正向迭代器:IteratorFactory.getLoopIterator()
  • 循环逆向迭代器:IteratorFactory.getLoopReverseIterator()

并且这些迭代器都可以接受两个参数:

  1. 集合:可以是数组、对象、集合
  2. 消费者函数:每次迭代如何处理这些数据

注意

对于对象、集合,迭代器会将其转换为元组进行迭代,比如

javascript
const obj = {a: 1, b: 2, c: 3};
=> 转换为:[["a", 1], ["b", 2], ["c", 3]]

下面通过正向迭代器和循环逆向迭代器来将进行演示:

正向迭代器

javascript
// 传递数组获取正向迭代器
let hobbyArr = ['篮球', '足球', '乒乓球'];
const iterator = IteratorFactory.getIterator(hobbyArr);
const userModel = defineModel('user', {
  id: 'string.uuid',
  hobby: () => {
    return iterator.next().value;
  },
});
console.log(fakeData(userModel, 4));

正向迭代器默认不会带有数据循环功能,比如上面生成了 4 个数据,由于hobbyArr只有 3 个且不会循环,所以第 4 个数据是undefined

json
[
  { "id": "d16e7a49-5e7a-40a0-97e7-68693ffa7268", "hobby": "篮球" },
  { "id": "268a6a63-5eee-4668-a166-d1b9f8bcf510", "hobby": "足球" },
  { "id": "2ed907c6-0cdf-40bd-95cf-6aaf3ebe5d1c", "hobby": "乒乓球" },
  { "id": "7d9b0df7-7fd3-401d-a7a9-59759a0948b4", "hobby": undefined }
]

循环逆向迭代器

循环逆向迭代器

javascript
// 传递map集合
let hobbyMap = new Map().set('h1', '篮球').set('h2', '足球').set('h3', '乒乓球');
// 获取循环逆向迭代器
const loopReverseIterator = IteratorFactory.getLoopReverseIterator(hobbyMap);
const userModel = defineModel('user', {
  id: 'string.uuid',
  reverseloopHobby: () => {
    // 每个value都是一个数组,第一个元素是key,第二个元素是value
    return loopReverseIterator.next().value[1];
  },
});
console.log(fakeData(userModel, 6));

最终结果是循环利用map集合中每个value进行迭代,生成 10 个数据。

json
[
  {
    "id": "418b79fc-acc5-4f94-8a2b-c23c9888d58c",
    "reverseloopHobby": "乒乓球"
  },
  {
    "id": "5e58c037-8bff-4bed-84e1-959bdcbf8836",
    "reverseloopHobby": "足球"
  },
  {
    "id": "9241aa2f-48f0-4a5b-9a06-c86213b8850c",
    "reverseloopHobby": "篮球"
  },
  {
    "id": "3f044540-7f82-465a-a9d4-61df2c065979",
    "reverseloopHobby": "乒乓球"
  },
  {
    "id": "ef564926-9446-4bd2-b3eb-ac320cace7e4",
    "reverseloopHobby": "足球"
  },
  {
    "id": "21f88c20-ebbc-4fd7-bcc2-3b6e63d1935f",
    "reverseloopHobby": "篮球"
  }
]

消费者模式

DataFaker在迭代器中使用了消费者模式,你可以事先传入一个函数,在每次迭代时使用该函数对数据进行处理。或者每次迭代时传入函数来处理数据。

统一处理函数

你可以在获取迭代器的时候传入一个统一处理函数,每次迭代都会调用该函数对数据进行处理。

javascript
let hobbyMap = new Map().set('h1', '篮球').set('h2', '足球').set('h3', '乒乓球');
// 传入统一处理函数,直接返回value
const loopReverseIterator = IteratorFactory.getLoopReverseIterator(hobbyMap, item => {
  return item[1];
});
const userModel = defineModel('user', {
  id: 'string.uuid',
  reverseloopHobby: () => {
    // 不再需要使用value[1]了,因为统一处理函数已经进行了处理
    return loopReverseIterator.next().value;
  },
});
console.log(fakeData(userModel, 6));

生成结果如下:

json
[
  {
    "id": "df991693-6303-4116-9bf5-171f67d20aa2",
    "reverseloopHobby": "乒乓球"
  },
  {
    "id": "27db5a7d-10fb-4beb-bd5c-650a99470bd9",
    "reverseloopHobby": "足球"
  },
  {
    "id": "93aacfe6-af38-4fda-aac1-b3e76e8bd269",
    "reverseloopHobby": "篮球"
  },
  {
    "id": "644dddf9-b1c1-43ed-97b8-d81eed32bc7f",
    "reverseloopHobby": "乒乓球"
  },
  {
    "id": "b08fb3a8-aba5-4a48-b694-211fea09a9b1",
    "reverseloopHobby": "足球"
  },
  {
    "id": "8bb61d87-3925-4420-9376-3e9ede2bdf31",
    "reverseloopHobby": "篮球"
  }
]

迭代时处理函数

或者你也可以在每次迭代时传入一个处理函数,每次迭代都会调用该函数对数据进行处理。这个优先级比统一处理函数高,但是只能从第二次迭代开始才起作用。

javascript
let hobbyMap = new Map().set('h1', '篮球').set('h2', '足球').set('h3', '乒乓球');
// 传入统一处理函数
const loopReverseIterator = IteratorFactory.getLoopReverseIterator(hobbyMap, item => {
  return item[1];
});
const userModel = defineModel('user', {
  id: 'string.uuid',
  reverseloopHobby: () => {
    // 每次迭代都会调用该函数对数据进行处理(优先级比统一处理函数高,但是从第二次进行)
    return loopReverseIterator.next((item, i) => {
      return item[1] + `${i}`;
    }).value;
  },
});
console.log(fakeData(userModel, 6));