生成器、迭代器、async/await的使用

迭代器-Iterator

1. 创建一个最基本的迭代器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const names = ["a", "b", "c"];

// 创建一个names的迭代器
// 1.迭代器是一个对象,该对象里必须有next方法
// 2.next方法必须返回一个对象,返回的对象必须包含done(布尔值)和value两个属性

let index = 0;
const nameInterator = {
next() {
if (index < names.length) {
return { done: false, value: names[index++] };
} else {
return { done: true, value: undefined };
}
},
};

console.log(nameInterator.next()); //{done: false, value: 'a'}
console.log(nameInterator.next()); //{done: false, value: 'b'}
console.log(nameInterator.next()); //{done: false, value: 'c'}
console.log(nameInterator.next()); //{done: true, value: undefined}

2. 创建一个数组通用迭代器的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const names = ["a", "b", "c"];
const nums = [1, 2, 3];

function createArrayIterator(arr) {
let index = 0;
return {
next() {
if (index < arr.length) {
return { done: false, value: arr[index++] };
} else {
return { done: true, value: undefined };
}
},
};
}

const namesIterator = createArrayIterator(names);
const numsIterator = createArrayIterator(nums);

可迭代对象

1. 创建一个基本的可迭代对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// 创建一个可迭代对象
// 1.必须实现一个特定的函数[Symbol.iterator]
// 2.这个函数必须返回一个迭代器

const info = {
names: ['a', 'b', 'c'],

[Symbol.iterator]() {
//迭代器
let index = 0
const infoInterator = {
//箭头函数使this指向info
next: => () {
if (index < this.names.length) {

return { done: false, value: this.names[index++] }
} else {

return { done: true, value: undefined }
}
}
}
//返回迭代器
return infoInterator
}
}

// 可迭代对象必然具备以下特点
// 执行对象的[Symbol.iterator]方法一定会获得一个迭代器
// 调用迭代器的next方法可以获取对应的元素

const infoInterator = info[Symbol.iterator]()

console.log(infoInterator.next()) //{done: false, value: 'a'}
console.log(infoInterator.next()) //{done: false, value: 'b'}
console.log(infoInterator.next()) //{done: false, value: 'b'}
console.log(infoInterator.next()) //{done: true, value: undefined}

//可迭代对象可以使用for..of
for (let item of info) {
//获取迭代返回对象的value值
console.log(item) //'a', 'b' ,'c'
}

//数组是一个可迭代对象
const nums = [1, 2, 3]
const numsIterator = nums[Symbol.iterator]()

console.log(numsIterator.next()) //{value: 1, done: false}
console.log(numsIterator.next()) //{value: 2, done: false}
console.log(numsIterator.next()) //{value: 2, done: false}
console.log(numsIterator.next()) //{value: undefined, done: true}

//String, Array, Map, Set, arguments都是可迭代对象

2. 自定义遍历对象的属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
const info = {
name: "aaa",
age: 20,
height: 1.88,
[Symbol.iterator]() {
const keys = Object.keys(this); //1.获取对象所有keys
const values = Object.keys(this); //2.获取对象所有values
const entries = Object.entries(this); //3.获取对象所有key-value

let index = 0;
const infoInterator = {
next() {
if (index < keys.length) {
return { done: false, value: keys[index++] };
} else {
return { done: true, value: undefined };
}
},
};
return infoInterator;
},
};
//1
for (let item of info) {
console.log(item); //'name', 'age', 'height'
}
//2
for (let item of info) {
console.log(item); //'aaa', 20, 1.88
}
//3
for (let item of info) {
console.log(item); //['name', 'aaa'], ['age', 18], ['height', 1.88]
}

生成器-generator

1. 创建一个基本的生成器函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 1.生成器函数需要在function后面加一个*
// 2.生成器函数可以使用yield关键字来控制
// 3.生成器函数的返回值是一个生成器对象
// 4.生成器是一个特殊的迭代器

function* foo() {
console.log("111");
//yield后面可以跟一个值 为迭代的value值 不传为undefined
yield "aaa";
console.log("222");
yield;
console.log("333");
}

const generator = foo();

//调用next方法开始执行函数 遇到yield则会暂停执行
generator.next(); // '111'
generator.next(); // '222'
generator.next(); // '333'

//遇到函数的return停止done变为true
console.log(generator.next()); // {value: 'aaa', done: false}
console.log(generator.next()); // {value: undefined, done: false}
console.log(generator.next()); // {value: undefined, done: true}

2. 生成器函数传递参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//next函数传递的参数需要在yield前面接收,第一个参数则在函数上接收

function* foo(msg1) {
console.log("111", msg1); // '111' '第一次调用next'
const msg2 = yield;
console.log("222", msg2); // '222' '第二次调用next'
const msg3 = yield;
console.log("333", msg3); // '333' '第二次调用next'
}

const generator = foo();
generator.next("第一次调用next");
generator.next("第二次调用next");
generator.next("第三次调用next");

3. 生成器优化迭代器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const names = ["a", "b", "c"];

function* createArrayIterator(arr) {
for (let i = 0; i < arr.length; i++) {
yield arr[i];
}
}

const namesIterator = createArrayIterator(names);
console.log(namesIterator.next()); // {value: 'a', done: false}
console.log(namesIterator.next()); // {value: 'b', done: false}
console.log(namesIterator.next()); // {value: 'c', done: false}
console.log(namesIterator.next()); // {value: undefined, done: true}

//2.使用yield*优化迭代器 yield*后面必须是一个可迭代对象,会自动遍历

function* createArrayIterator1(arr) {
//相当与上面的for循环
yield* arr;
}
const namesIterator = createArrayIterator1(names);
console.log(namesIterator.next()); // {value: 'a', done: false}
console.log(namesIterator.next()); // {value: 'b', done: false}
console.log(namesIterator.next()); // {value: 'c', done: false}
console.log(namesIterator.next()); // {value: undefined, done: true}

async/await

1. async 函数的返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// async用于声明异步函数
// async函数的返回值被promise包裹

async function foo() {
//不返回, 默认返回undefined
}
async function foo1() {
// 返回一个普通的值
return "123";
}
async function foo2() {
//返回一个promise 则由返回的promise来决定状态
return new Promise((resolve, reject) => {
resolve("aaa");
});
}
async function foo3() {
//返回一个thenable对象
return {
then(resolve, reject) {
resolve("bbb");
},
};
}

console.log(foo()); //Promise {<fulfilled>: undefined}
console.log(foo1()); //Promise {<fulfilled>: '123'}

foo2().then((res) => {
console.log(res); // 'aaa'
});

foo3().then((res) => {
console.log(res); // 'bbb'
});

2. await 的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("123");
}, 2000);
});
}

// await只能在异步函数中使用
// await会等到promise的状态变为fulfilled状态并返回resolve的值,才会继续执行后续代码

async function foo() {
const res = await getData();
//2秒钟之后才会执行后续代码
console.log("后续代码执行");
console.log(res); // '123'
}

foo();