如何让数组新增元素后Symbol.iterator迭代器可恢复继续输出?
问题解决
根本原因
- ES迭代器协议明确规定:迭代器一旦返回
done: true进入完成状态后,后续所有next()调用必须永久返回done: true,无法恢复迭代 - 你的代码全局仅初始化了一次数组默认迭代器,第一次执行
listAll()时迭代器已经走完所有原有元素进入完成状态,后续新增元素后再调用listAll()也不会有新的输出
解决方案
方案1:每次遍历新建迭代器(全量打印所有元素)
如果需求是每次调用listAll()都打印数组当前所有元素(包含之前已经打印过的元素),只需要把迭代器初始化逻辑放到listAll()函数内部即可:
let arr = [{ name : "Computer", sold : 1000 }, { name: "Printer", sold: 250 }, { name: "Camera", sold:290 }, { name: "Gamepad", sold: 800 }, { name: "Keyboard", sold: 2100 } ] const listAll = () => { // 每次调用都生成新的迭代器,从头遍历当前数组的全部元素 const iteratorArr = arr[Symbol.iterator](); var it = iteratorArr.next() while(!it.done) { console.log(it.value) it = iteratorArr.next() } } listAll() // 打印前5个初始元素 arr.push({name:"Mouse",sold: 2900}) listAll() // 打印全部6个元素,包含新增的Mouse
方案2:自定义可恢复迭代逻辑(增量打印仅新增元素)
如果需求是不重复打印已经输出过的元素,只打印每次新增的内容,自行维护遍历索引即可,不要用一次性的默认迭代器:
let arr = [{ name : "Computer", sold : 1000 }, { name: "Printer", sold: 250 }, { name: "Camera", sold:290 }, { name: "Gamepad", sold: 800 }, { name: "Keyboard", sold: 2100 } ] // 全局维护当前遍历到的索引位置 let currentScanIndex = 0 const listAll = () => { // 从上次停止的索引开始遍历,直到数组当前长度 while(currentScanIndex < arr.length) { console.log(arr[currentScanIndex]) currentScanIndex++ } } listAll() // 打印前5个初始元素,索引停在5 arr.push({name:"Mouse",sold: 2900}) // 数组长度变为6 listAll() // 从索引5开始遍历,仅打印新增的Mouse,无重复输出
内容的提问来源于stack exchange,提问作者Enes Giray
相关产品推荐
相关产品推荐

