1.为啥要使用迭代器
2.迭代器
可以理解为更清晰的循环语句。 迭代器都有next()方法,每次调用都会返回两个属性的结果对象。 一个是value(此次迭代返回的值),一个是done(布尔类型,如果为true则表示后续没有继续返回的值了)
function createIterator(items) {
var i = 0;
return {
next: function() {
var done = (i >= items.length);
var value = !done ? items[i++] : undefined;
return {
done: done,
value: value
};
}
};
}
var iterator = createIterator([1, 2, 3]);
console.log(iterator.next()); // "{ value: 1, done: false }"
console.log(iterator.next()); // "{ value: 2, done: false }"
console.log(iterator.next()); // "{ value: 3, done: false }"
console.log(iterator.next()); // "{ value: undefined, done: true }"
// 之后的所有调用
console.log(iterator.next()); // "{ value: undefined, done: true }"
3.生成器
专门放迭代器的。 生成器也有next()方法,通过*来表示该函数会用到yield。
function *createIterator(){
yield 'aaa';
yield 'bbb';
yield 4;
}
let resa=createIterator()
console.log(resa.next().value);
每当执行完一条yield就会自动停止,直到你下次使用会调用下一次的yield。 yield关键字只能在生成器内使用,否则会报错。
可迭代对象
Symbol.iterator方法可以跟踪内部的相关问题。 例如: 可通过for-of代码多次调用next()方法
let values = [1, 2, 3];
for (let num of values) {
//1
//2
//3
console.log(num);
}
也可通过Symbol.iterator来访问对象默认的迭代器
let val=[1,2,3];
let iterator=val[Symbol.iterator]();
console.log(iterator.next());//1
检测是否是可迭代对象
function isIterable(object) {
return typeof object[Symbol.iterator] === "function";
}
console.log(isIterable([1,2,4]));// true
console.log(isIterable(new Map())); // true
创建可迭代对象 正常来说,对象内部的数据是不可以迭代的,但如果给Symbol.iterator添加生成器,是可以做到迭代的
let collection={
items:[11,33,55],
*[Symbol.iterator](){
for(let item of this.items){
yield item;
}
}
}
collection.items.push(1);
for (let x of collection){
console.log(x);
}
内建迭代器
集合对象的迭代器:数组,map,set enteries()返回一个迭代器,值为多个键值对 values()返回一个迭代器,值为集合的值 keys()返回一个迭代器,值为集合中的所有键名 这里只演示一个entries
let colors = [ "red", "green", "blue" ];
let tracking = new Set([1234, 5678, 9012]);
let data = new Map();
data.set("title", "Understanding ES6");
data.set("format", "ebook");
for (let entry of colors.entries()) {
console.log(entry);
}
for (let entry of tracking.entries()) {
console.log(entry);
}
for (let entry of data.entries()) {
console.log(entry);
}
[0, "red"]
[1, "green"]
[2, "blue"]
[1234, 1234]
[5678, 5678]
[9012, 9012]
["title", "Understanding ES6"]
["format", "ebook"]
其实,迭代器也可以处理dom元素,dom元素有一个NodeList类型
var divs=document.getElementsByTagName('h1');
for (let h of divs)
console.log(h);
}
高级迭代器
1.给迭代器传递参数,由于每调用一次next()方法的参数会代替上一次的yield值,所以第一次的传参没有意义。
function *createIterator() {
let first = yield 1;
let second = yield first + 2; // 4 + 2
}
let iterator = createIterator();
console.log(iterator.next());
console.log(iterator.next(4);//传入4,first变量为4
2.迭代器的返回语句
function *createIterator() {
yield 1;
return;
yield 2;
}
let iterator = createIterator();
console.log(iterator.next()); // "{ value: 1, done: false }"
console.log(iterator.next()); // "{ value: undefined, done: true }"
//return之后,将不在进行之后的yield,值为返回参数,但也只能返回一次,之后就是undefined。
3.委托生成器
就是将多个迭代器放在生成器里
function *createNumberIterator() {
yield 1;
yield 2;
}
function *createColorIterator() {
yield "red";
yield "green";
}
function *createCombinedIterator() {
yield *createNumberIterator();
yield *createColorIterator();
yield true;
}
var resa=createNumberIterator();
var iterator = createCombinedIterator();
console.log(resa.next()); // "{ value: 1, done: false }"
console.log(iterator.next()); // "{ value: 2, done: false }"
console.log(iterator.next()); // "{ value: "red", done: false }"
console.log(iterator.next()); // "{ value: "green", done: false }"
换汤不换药,超级简单有木有~~~~
4.同步异步的迭代器
最后一个知识点,坚持住....写到这儿其实我也累了
简单的任务执行器(向任务执行器传递数据) ,因为我们的yield通过next会被不停的覆盖。通过run()方法就可以使返回的结果保存起来使用。step()会检查result.done的值,如果为true了,则不继续执行step()操作了。
好了,废话太多了,来个例子吧。
function run(taskDef) {
let task=taskDef();
let res=task.next();
function step() {
if(!res.done){
res=task.next(res.value);
step()
}
}
step();
}
run(function *(){
let value=yield 1;
console.log(value);
value=yield value+4;
console.log(value);//5,因为yield 1被存住了。
})