从生成器函数获取先前的值

时间:2019-09-28 02:18:13

标签: javascript function ecmascript-6

我对生成器函数还比较陌生,想知道是否有办法从生成器函数中获得先前的值。我知道我可以使用.next()进行下一个yield,但是我想知道是否有可能做类似.prev()的事情,这实际上可以退一步。 / p>

我希望.prev()可以工作,但是不幸的是,它不会:

const array = ['a', 'b', 'c'];

function* f(array) {
  let i = 0;
  while(true) {
    yield array[i];
    i = (i+1) % array.length;
  }
}

const seq = f(array);
console.log(seq.next().value); // a
console.log(seq.next().value); // b
console.log(seq.next().value); // c

console.log(seq.next().value); // a

// console.log(seq.prev().value); // c <-- expect 'c'

正如我提到的,我对生成器没有经验,如果有更好的数据结构/方法来逐步获取值(上一个和下一个),我很乐意听到这些建议

1 个答案:

答案 0 :(得分:0)

您可以让生成器检查yield的结果,如果它是某个表达式(例如'prev'),则递减i而不是递增:

const array = ['a', 'b', 'c'];

function* f(array) {
  let i = 0;
  while (true) {
    const incOrDec = (yield array[i]) === 'prev' ? -1 : 1;
    i = (array.length + i + incOrDec) % array.length;
  }
}

const seq = f(array);
console.log(seq.next().value); // a
console.log(seq.next().value); // b
console.log(seq.next().value); // c

console.log(seq.next().value); // a

console.log(seq.next('prev').value); // c <-- expect 'c'

如果不将功能内置到生成器中,则必须将上一次迭代的结果显式保存在变量中,然后进行检查。没有像.prev这样的内置方法。

  

我对生成器没有经验,如果有更好的数据结构/方法可以逐步获取值(上一个和下一个),我很乐意听到这些建议

如果您没有与发电机一起工作,而您的目的是能够前后迭代,那么就不要。如果从生成器开始(就像无法控制的外部功能一样),则可以使用与上述方法类似的方法将生成器转换为可以前后导航的方法。否则,只需使用将值放入其中并在其上查找索引的普通数组即可,例如:

const array = ['a', 'b', 'c'];

function* f(array) {
  let i = 0;
  while (true) {
    const incOrDec = (yield array[i]) === 'prev' ? -1 : 1;
    i = (array.length + i + incOrDec) % array.length;
  }
}

const cache = [];
const getValue = i => cache[i] || (cache[i] = /* put logic for retrieving value here */ array[i % array.length]);

console.log(getValue(0));
console.log(getValue(1));
console.log(getValue(2));
console.log(getValue(3));
console.log(getValue(4));
console.log(getValue(3));