一、迭代器
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作。
(1)ES6创造了一种新的命令 for...of... 循环,Iterator 接口主要供for...of消费
(2)原生具备iterator接口的数据(可用for...of遍历)
Array,Arguments,Set,Map,String,TypeArray,NodeList
//声明一个数组
const TNT = ['马嘉祺','丁程鑫','宋亚轩','刘耀文','张真源','严浩翔','贺峻霖'];
//使用for...of循环 遍历数组
for(let v of TNT){
console.log(v);
}
(3)工作原理
a. 创建一个指针对象,指向当前数据结构的起始位置;
b. 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员;
c. 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员;
d. 每调用 next 方法返回一个包含 value 和 done 属性的对象;
注:需要自定义遍历数据的时候,要想到迭代器
//声明一个数组
const TNT = ['马嘉祺','丁程鑫','宋亚轩','刘耀文','张真源','严浩翔','贺峻霖'];
//使用for...of循环 遍历数组
for(let v of TNT){
console.log(v);
}
let iterator = TNT[Symbol.iterator]();
//调用Symbol对象的next方法
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
//重新初始化对象,指针也会重新回到最前面
let iterator2 = TNT[Symbol.iterator]();
console.log(iterator2.next());
迭代器自定义遍历对象
//迭代器自定义遍历对象
//声明一个对象
const TNT = {
name: '时代少年团',
remember: [
'马嘉祺',
'丁程鑫',
'宋亚轩',
'刘耀文',
'张真源',
'贺峻霖',
'严浩翔'
]
,
[Symbol.iterator]() {
let index = 0;
//保存this
let _this = this;
return {
next: function () {
if (index < _this.remember.length) {
const result = {
value: _this.remember[index],
done: false
};
index++;
return result;
}else {
return {
value:undefined,
done: true
};
}
}
};
}
}
for(let v of TNT){
console.log(v);
}
二、生成器
生成器函数是es6提供方的一种异步编程解决方案,语法行为与传统函数完全不同
//生成器函数参数的传递
function * gen(args) {
console.log(args);
let one = yield 111;
let two = yield 222;
let three = yield 333;
console.log(one);
console.log(two);
console.log(three);
}
//获取迭代器对象
let iterator = gen('AAA');
console.log(iterator.next());//会执行yield 111;
//next方法也可以传入参数,传入的参数作为第一条(上一条)语句yield 111的返回结果
console.log(iterator.next('宋亚轩'));//会执行yield 222;
console.log(iterator.next('刘耀文'));//会执行yield 333;
console.log(iterator.next('文轩'));//继续往后走,但是这里未定义;
实例:
// 生成器其实就是一个特殊的函数
// 异步编程 纯回调函数 node fs ajax mongodb
// yield:函数代码的分隔符
function* gen(args) {
console.log(args);
// let one = yield 111;
// let two = yield 222;
// let three = yield 333;
console.log('one');
yield 'AAA';
console.log('two');
yield 'BBB';
console.log('three');
yield 'CCC';
}
//获取迭代器对象
let iterator = gen();
console.log(iterator.next());
//next方法也可以传入实参
console.log(iterator.next('宋亚轩'));
console.log(iterator.next('刘耀文'));
console.log(iterator.next('文轩'));
console.log("遍历:");
for(let v of gen()){
console.log(v);
}
案例一:异步编程、文件操作、网络操作(ajax request)、数据库操作
需求:一秒后弹出111,两秒后弹出222,三秒后弹出333
回调地狱
setTimeout(()=>{
alert(111);
setTimeout(()=>{
alert(222);
setTimeout(()=>{
alert(333);
},3000)
},2000)
},1000)
//另一种方法
function first(){
setTimeout(()=>{
alert(111);
console.log(111);
iterator.next();
},1000);
}
function second(){
setTimeout(()=>{
alert(222);
console.log(111);
iterator.next();
},1000)
}
function third(){
setTimeout(()=>{
alert(333);
console.log(111);
iterator.next();
},1000)
}
function * gen() {
yield first();
yield second();
yield third();
}
let iterator = gen();
iterator.next();
三、promise
Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作 并可以获取其成功或失败的结果;
1. Promise 构造函数: Promise (excutor) {};
2. Promise.prototype.then 方法;
3. Promise.prototype.catch 方法;
//实例化Promise 对象
//Promise 对象的三种状态:初始化、成功、失败
const p = new Promise(function(resolve, reject){
setTimeout(function(){
//成功
let data = "数据";
resolve(data);
//失败
let err = "失败!!";
reject(err);
},1000);
});
//调用 Promise 的 then 方法,两个参数为函数
p.then(function(value){
//成功
console.log(value);
},function(season){
//失败
console.log(season);
})
1.Promise 封装读取函数
一般写法
//Promise封装读取函数
//一般写法
//1.引入fs模块
const fs = require("fs");
//2.调用方法读取文件
fs.readFile("11-es8/resource/为学.md",(err,data)=>{
//若果失败抛出错误
if(err) throw err;
//如果没有出错则输出内容
console.log(data.toString());
})
浏览器端不能识别require关键字,require是node.js环境下的,在node_modules文件夹里面的模块下面常见require
promise封装
//1.引入fs模块
const fs = require("fs");
//promise封装
const p = new Promise(function(resolve,data){
fs.readFile("11-es8/resource/为学.md",(err,data)=>{
//判断如果失败
if(err) PromiseRejectionEvent(err);
//如果成功
resolve(data);
})
})
p.then(function(value){
console.log(value.toString());
},function(reason){
console.log(reason);
})
2. Promise封装Ajax请求
原生请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Promise封装Ajax请求</title>
</head>
<body>
<script>
//请求地址:https://api.apiopen.top/getJoke
//原生请求
//1.创建对象
const xhr = new XMLHttpRequest();
//2.初始化
xhr.open("GET","https://api.apiopen.top/getJoke");
//3.发送
xhr.send();
//4.绑定事件,处理响应结果
xhr.onreadystatechange = function(){
//判断状态
if(xhr.readyState == 4) {
//判断响应状态码
if(xhr.status>=200&&xhr.status<300){
//成功
console.log(xhr.response);
}else{
//失败
console.error(xhr.status);
}
}
}
</script>
</body>
</html>
响应成功的网址内容
promise封装ajax请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Promise封装Ajax请求</title>
</head>
<body>
<script>
//请求地址:https://api.apiopen.top/getJoke
const p = new Promise(function(resolve,reason){
//原生请求
//1.创建对象
const xhr = new XMLHttpRequest();
//2.初始化
xhr.open("GET","https://api.apiopen.top/getJoke");
//3.发送
xhr.send();
//4.绑定事件,处理响应结果
xhr.onreadystatechange = function(){
//判断状态
if(xhr.readyState == 4) {
//判断响应状态码
if(xhr.status>=200&&xhr.status<300){
//成功
console.log(xhr.response);
}else{
//失败
console.error(xhr.status);
}
}
}
});
p.then(function(value){
console.log(value.toString());
},function(reason){
console.error(reason);
})
</script>
</body>
</html>
响应成功时
响应失败时
3.Promise.prototype.then
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>promise.prototype.then</title>
</head>
<body>
<script>
//创建 Promise 对象
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("用户数据");
},1000);
});
//调用then方法,then方法返回的是Promise对象
//对象的状态由回调函数的结果决定
const result = p.then(value => {
console.log(value);
//1.如果回调函数中返回的结果是 非Promise 类型的数据
//状态为成功,返回值为对象的草稿纸resolved
// [[PromiseStatus]]:"resolved"
// [[PromiseValue]]:"123"
// return 123;
//如果是Promise类型的数据
//此Promise对象的状态决定上面Promise对象p的状态
// return new Promise((resolve,reject)=>{
// resolve("okk");
// reject("noo");
// });
//3.抛出错误
throw new Error("lose!!!");
//状态:rejected
//value:lose!!!
},reason=>{
console.error(reason);
})
//链式调用
//then里面的两个函数参数可以只写一个
p.then(value=>{},reason=>{}).then(value=>{},reason=>{});
console.log(result);
</script>
</body>
</html>
4.Promise对象catch方法
很多情况我们只需传promise的成功态(resolved)下调用的then方法的第一个处理函数,所以为了更好的语义化,我们使用then方法专门处理resolved态,使用catch方法专门处理rejected态。
相当于then(null,err => {}); 不处理成功态,只处理失败态。
目录
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
//设置p的状态为失败,并设置失败的值
reject("lose!!!");
},1000);
})
p.catch(reason=>{
console.warn(reason);
});
</script>
</body>
</html>