ES6学习24~47

2.14 Promise

2.14.1 什么是Promise

Promise是ES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。

  1. Promise 构造函数: Promise (excutor) {}
  2. Promise.prototype.then 方法
  3. Promise.prototype.catch 方法

2.14.2 promise的好处

1.可以避免多层异步调用嵌套问题(即回调地狱)

2.Promise 对象提供了简洁的API,使得控制异步操作更加容易(js执行机制导致的异步问题)

2.14.3 promise的三种状态

  1. pending: 等待中,或者进行中,表示还没有得到结果
  2. resolved(Fulfilled): 已经完成,表示得到了我们想要的结果,可以继续往下执行
  3. rejected: 也表示得到结果,但是由于结果并非我们所愿,因此拒绝执行

这三种状态不受外界影响,而且状态只能从pending改变为resolved或者rejected,并且不可逆

2.14.4 promise的用法

  1. promise的实例方法
  • then()得到异步任务的正确结果
  • catch()获取异常信息
  • finally()成功与否都会执行(尚且不是正式标准)

then方法可以接受两个函数,第一个函数为promise状态为成功的回调函数,第二个函数为promise状态为失败的回调函数(可以不写,一般用catch方法捕获promise状态为失败的异常信息)

  1. promise的对象方法(p1,p2,p3为promise的实例对象)
  • Promise.all()并发处理多个异步任务,所有任务都执行完成才能得到结果
Promise.all([p1, p2, p3]).then((result) => {
    console.log(result);
})
  • Promise.race()并发处理多个异步任务,只要有一个任务完成就能得到结果
Promise.race ( [p1,p2,p3] ).then ((result) => {
    console. log (result)
})

2.14.5 promise的特点

  1. 在Promise对象的构造函数中,将一个函数作为第一个参数。
  2. 而Promise对象的构造函数的第一个参数中的这个函数,就是用来处理Promise的状态变化,这个函数的第一个参数表示promise的状态为成功第二个参数表示promise的状态为失败,这两个参数(名字可以自己命名)都为一个函数,他们的作用分别是将promise状态修改为resolved(成功)rejected(失败)
const p = new Promise(function(resolve,reject) {
    setTimeout(function() {
        // let data = '数据库中的用户数据';
        // resolve
        // resolve(data);
        let err = '数据读取失败';
        reject(err);
    }, 1000)
});
// 调用promise对象的then方法
p.then(function(value) {
    console.log(value);
}, function(reason) {
    console.log(reason);
});
Promise读取文件
// 1. 引入fs模块
const fs = require('fs');
const { writer } = require('repl');

// 2. 调用方法
// fs.readFile('./resources/为学.md', (err, data) => {
//     // 如果失败 则抛出错误
//     if (err) throw err;
//     // 如果没有出错 则输出内容
//     console.log(data.toString());
// });

// 3. 使用Promise封装
const p = new Promise(function (resolve, reject) {
    fs.readFile("./resources/为学.md", (err, data) => {
        // 判断如果失败
        if (err) reject(err);
        // 如果成功
        resolve(data);
    });
});

p.then(function (value) {
    console.log(value.toString());
 }, function (reason) {
    console.log("读取失败!!!");
})

打开终端,输入:node 02/Promise读取文件.js

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>发送AJAX</title>
  </head>
  <body>
    <script>
      // 接口地址:https://api.apiopen.top/getJoke
      const p = new Promise((resolve, reject) => {
        // 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) {
            // 判断响应状态码 200-299
            if (xhr.status >= 200 && xhr.status < 300) {
              // 表示成功
              resolve(xhr.response);
            } else {
              //  如果失败
              reject(xhr.status);
            }
          }
        };
      });

    //   指定回调
    p.then(function(value) {
        console.log(value);
    }, function(reason) {
        console.error(reason);
    })
    </script>
  </body>
</html>

2.14.6 Promise的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对象 对象状态由回调函数阿执行结果决定
        // 1. 如果回调函数中返回的结果是 非promise类型的属性 状态为成功 返回值为对象的成功的值
        // const result = p.then(value => {
            // console.log(value);
            // 1. 非promise类型的属性
            // return 123;
            // 2. 是promise对象
            // return new Promise((resolve, reject) => {
            //     // resolve('ok');
            //     reject('error');
            // });
            // 3. 抛出错误
            // throw '出错啦!';
        // }, reason => {
        //     console.warn(reason);
        // })
        // console.log(result);

        // 链式调用
        p.then(value => {

        }).then(value => {

        })
        
    </script>
</body>
</html>
Promise实践-读取多个文件
// 引入fs模块
const fs = require("fs");

// fs.readFile('./resources/为学.md', (err, data1) => {
//     fs.readFile('./resources/插秧诗.md', (err, data2) => {
//         fs.readFile('./resources/观书有感.md', (err, data3) => {
//             let result = data1 + '\r\n' + data2 + '\r\n' + data3;
//             console.log(result);
//         });
//     });
// });

// 使用promise实现
const p = new Promise((resolve, reject) => {
    fs.readFile("./resources/为学.md", (err, data) => {
        resolve(data);
    });
});

p.then(value => {
    return new Promise((resolve, reject) => {
        fs.readFile("./resources/插秧诗.md", (err, data) => {
            resolve([value, data]);
        });
    })
}).then(value => {
    return new Promise((resolve, reject) => {
        fs.readFile("./resources/观书有感.md", (err, data) => {
            // 压入
            value.push(data);
            resolve(value);
        });
    })
}).then(value => {
    console.log(value.join('\r\n'));
})

2.14.7 Promise的catch方法

相当于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>catch方法</title>
</head>
<body>
    <script>
        const p = new Promise((resolve, reject) => {
            setTimeout(() => {
                // 设置p对象的状态为失败 并设置失败的值
                reject("出错啦!");
            }, 1000)
        });

        // p.then(function(value){}, function(reaosn){
        //     console.log(reason);
        // });

        p.catch(function(reason) {
            console.log(reason);
        })
    </script>
</body>
</html>

2.15 Set

ES6提供了新的数据结构Set(集合)。它类似于数组,但成员的值都是唯
一的,集合实现了iterator接口,所以可以使用「扩展运算符」和「for…of…」进行遍历,集合的属性和方法:

  1. size 返回集合的元素个数
  2. add 增加一个新元素,返回当前集合
  3. delete 删除元素,返回boolean 值
  4. has 检测集合中是否包含某个元素,返回boolean值
  5. clear 清空集合,返回undefined
// 创建一个空集合
let s = new Set();
// 创建一个非空集合
let s1 = new Set([1, 2, 3, 1, 2, 3]);
// 返回集合元素个数
console.log(s2.size);
// 添加新的元素
s2.add('喜事儿');
// 删除元素
s2.delete('坏事儿');
// 检测是否存在某个值
console.log(s2.has('糟心事'));
// 清空集合
s2.clear();

2.16 Map

ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是“键”
的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现
了iterator接口,所以可以使用[扩展运算]和[for…of…]进行遍历。Map
的属性和方法:

  1. size 返回Map的元素个数
  2. set 增加一个新元素,返回当前Map
  3. get 返回键名对象的值
  4. has 检测Map中是否包含某个元素,返回boolean值
  5. clear 清空集合,返回undefined
// 创建一个空map
let m = new Map();
// 创建一个非空map
let m2 = new Map([
    ['name','尚硅谷'],
    ['slogon','不断提高行业标准']
]);
//属性和方法
//获取映射元素的个数
console. log(m2.size);
//添加映射值
console.log(m2.set('age'
, 6));
//获取映射值
console.log(m2.get('age'));
//检测是否有该映射
console.log(m2.has('age'));
//清除
console.log (m2.clear());

2.17 class类

ES6提供了更接近传统语言的写法,引入了Class (类)这个概念,作为对
象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而己。

知识点:

  1. class声明类
  2. constructor定义构造函数初始化
  3. extends继承父类
  4. super调用父类构造方法
  5. static定义静态方法和属性
  6. 父类方法可以重写

eg:

<!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>类声明</title>
</head>
<body>
    <script>
        // ES5
        // 手机
        // function Phone(brand, price) {
        //     this.brand = brand;
        //     this.price = price;
        // }

        // // 添加方法
        // Phone.prototype.call = function() {
        //     console.log("我可以打电话!!");
        // }

        // // 实例化对象
        // let Huawei = new Phone('华为', 5999);
        // Huawei.call();
        // console.log(Huawei);

        // class
        class Phone {
            // 构造方法 名字不能修改
            constructor(brand, price) {
                this.brand = brand;
                this.price = price;
            }
            // 方法必须使用该语法,不能使用ES5的对象完整形式
            call() {
                console.log("我可以打电话!!");
            }
        }
        let onePlus = new Phone("1 + ", 1999);

        console.log(onePlus);
    </script>
</body>
</html>

eg:类的静态成员

<!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>静态成员</title>
</head>
<body>
    <script>
        // function Phone() {

        // }
        // Phone.name ='手机';
        // Phone.change = function() {
        //     console.log("我可以改变世界");
        // }
        // Phone.prototype.size = '5.5inch';
        // let nokia = new Phone();
        
        // console.log(nokia.name); // undefined
        // // nokia.change();
        // console.log(nokia.size); // 5.5inch

        class Phone {
            static name = '手机';
            static change() {
                console.log("我可以改变世界");
            }
        }
        let nokia = new Phone();
        console.log(nokia.name); // undefined
        console.log(Phone.name); // 手机
    </script>
</body>
</html>

eg:ES5构造函数的继承

<!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>对象继承</title>
</head>
<body>
    <script>
        // ES5构造函数的继承
        // 手机
        function Phone(brand, price) {
            this.brand = brand;
            this.price = price;
        }

        Phone.prototype.call = function() {
            console.log("我可以打电话");
        }

        // 智能手机
        function SmartPhone(brand, price, color, size) {
            Phone.call(this, brand, price);
            this.color = color;
            this.size = size;
        }

        // 设置子级构造函数的原型
        SmartPhone.prototype  = new Phone;
        SmartPhone.prototype.constructor = SmartPhone;

        // 声明子类的方法
        SmartPhone.prototype.photo = function() {
            console.log("我可以拍照");
        }

        SmartPhone.prototype.playGame = function() {
            console.log("我可以玩游戏");
        }

        const chuizi = new SmartPhone('锤子', 2499, '黑色', '5.5inch');

        console.log(chuizi);
    </script>
</body>
</html>

eg:ES6类继承和子类对父类方法的重写

<!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>类继承-2</title>
</head>
<body>
    <script>
        class Phone {
            // 构造方法
            constructor(brand, price) {
                this.brand = bramd;
                this.price = price;
            }

            // 父类的成员属性
            call() {
                console.log("我可以打电话!!");
            }
        }

        class SmartPhone extends Phone {
            // 构造方法
            constructor(brand, price, color, size) {
                super(brand, price);
                this.color = color;
                this.size = size;
            }
            photo() {
                console.log("拍照");
            }
            playGame() {
                console.log("玩游戏");
            }
            // 子类对父类方法的重写
            call() {
                console.log("我可以进行视频通话");
            }
        }
        const xiaomi = new SmartPhone('小米', 799, '黑色', '4.7inch');
        // console.log(xiaomi);
        xiaomi.call();
        xiaomi.photo();
        xiaomi.playGame();
    </script>
</body>
</html>

class中的getter和setter设置

<!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>get 和 set</title>
</head>
<body>
    <script>
        // get 和 set
        class Phone {
            get price() {
                console.log("价格属性被读取了");
                return "i love you"
            }
            set price(newVal) {
                console.log('价格属性被修改了');
            }
        }

        // 实例化对象
        let s = new Phone();

        // console.log(s.price);
        s.price = 'free'
    </script>
</body>
</html>

2.18 数值扩展

2.18.1 二进制和八进制

ES6提供了二进制和八进制数值的新的写法,分别用前缀0b和0o表示。

2.18.2 Number.isFinite()与Number.isNaN()

Number.isFinite()用来检查一个数值是否为有限的
Number.isNaN()用来检查一个值是否为NaN

2.18.3 Number.parselnt()与Number.parseFloat()

ES6将全局方法parseInt和parseFloat,移植到Number对象上面,使用不变。

2.18.4 Math.trunc

用于去除一个数的小数部分,返回整数部分。

2.18.5 Number.isInteger

Number.isInteger()用来判断一个数值是否为整数

<!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>数值扩展</title>
</head>
<body>
    <script>
        // 0. Number.EPSILON 是JavaScript表示的最小精度
        // EPSILON 属性的值接近于2.220446049250310808472633361816E-16
        console.log(0.1 + 0.2 === 0.3);
        function equal(a, b) {
            if (Math.abs(a - b) < Number.EPSILON) {
                return true;
            } else {
                return false;
            }
        }
        console.log(0.1 + 0.2 === 0.3);
        console.log(equal(0.1 + 0.2, 0.3));
        
        // 1. 二进制和八进制
        let b = 0b1010;
        let o = 0o777;
        let d = 100;
        let x = 0xff;
        console.log(x);
        
        // 2. Number.isFinite检测一个数值是否为有限数
        console.log(Number.isFinite(100));
        console.log(Number.isFinite(100/0));
        console.log(Number.isFinite(Infinity));

        // 3. Number.isNaN检测一个数值是否为NaN
        console.log(Number.isNaN(123));

        // 4. Number.parseInt Number.parseFloat字符串转整数
        console.log(Number.parseInt('521123love'));
        console.log(Number.parseFloat('3.1415926神奇'));
        
        // 5. Number.isInteger 判断一个数是否为整数
        console.log(Number.isInteger(5));
        console.log(Number.isInteger(2.5));

        // 6. Math.trunc 将数字的小数部分抹掉
        console.log(Math.trunc(3.5));

        // 7. Math.sign 判断一个数到底是正数 负数 还是0
        console.log(Math.sign(100)); // 1
        console.log(Math.sign(0)); // 0
        console.log(Math.sign(-2000)); // -1
    </script>
</body>
</html>

2.19 对象扩展

ES6新增了一些Object对象的方法

  1. Object.is 比较两个值是否严格相等,与「===」 行为基本一致(+0与NaN)
  2. Object.assign 对象的合并,将源对象的所有可枚举属性,复制到目标对象
  3. proto_、setPrototypeOf、setPrototypeOf可以直接设置对象的原型
<!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>对象方法扩展</title>
</head>
<body>
    <script>
        // 1. Object.is 判断两个值是否完全相等
        console.log(Object.is(200, 200)); // true
        console.log(Object.is(NaN, NaN)); // true
        console.log(NaN === NaN); // ===

        // 2. Object.assign对象的合并
        const config1 = {
            host:'localhost',
            port: 3306,
            name: 'root',
            pass: 'root',
            test: 'test'
        };

        const config2 = {
            host:'http://atguigu.com',
            port: 33060,
            name: 'atguigu.com',
            pass: 'iloveyou',
            test2: 'test2'
        };
        console.log(Object.assign(config1, config2));
        
        // 3. Object.setPrototypeOf Object.getPrototypeOf
        const school = {
            name: 'yaya'
        }
        const cities = {
            xiaoqu: ['北京', '上海', '深圳']
        }

        Object.setPrototypeOf(school, cities);
        console.log(Object.getPrototypeOf(school));
        console.log(school);
    </script>
</body>
</html>

2.20 模块化

模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。

2.20.1 模块化的好处

模块化的优势有以下几点:

  1. 防止命名冲突
  2. 代码复用
  3. 高维护性

2.20.2 模块化规范产品

ES6之前的模块化规范有:

  1. CommonJS => NodeJS、 Browserify
  2. AMD => requireJS ,
  3. CMD => seaJS

2.20.3 ES6模块化语法

模块功能主要由两个命令构成:export和import。

  • export 命令用于规定模块的对外接口
  • import命令用于输入其他模块提供的功能
  1. 分别暴露
// 分别暴露
export let school = 'yaya'

export function teach() {
    console.log("我们可以教给你开发技能");
}
  1. 统一暴露
// 统一暴露
let school = 'yaya'

function findHappy() {
    console.log('我可以帮助你得到快乐');
}

export { school, findHappy };
  1. 默认暴露
// 默认暴露
export default {
    school: 'yaya',
    change: function () {
        console.log("我可以帮助你");
    }
}

index.html

<!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>ES6模块化</title>
</head>
<body>
    <script type="module">
        // 引入m1.js模块内容 将暴露的数据存到m1中
        import * as m1 from "./m1.js";
        console.log(m1);
        // 引入m2.jhs模块内容
        import * as m2 from "./m2.js";
        console.log(m2);
        // 引入m3.js模块内容
        import * as m3 from "./m3.js"
        console.log(m3);
    </script>
</body>
</html>

ES6引入模块数据语法
index.html

<!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>ES6模块化</title>
</head>
<body>
    <script type="module">
        // 1. 通用的导入方式
        // 引入m1.js模块内容
        // import * as m1 from "./m1.js";
        // console.log(m1);
        // // 引入m2.jhs模块内容
        // import * as m2 from "./m2.js";
        // console.log(m2);
        // // 引入m3.js模块内容
        // import * as m3 from "./m3.js"
        // console.log(m3);

        // 2. 解构赋值形式
        // import {school, teach} from './m1.js';
        // import {school as sc, findHappy} from "./m2.js"; 
        // import {default as m3} from "./m3.js";
        // // console.log(school);
        // // console.log(teach);
        // // console.log(sc, findHappy);
        // console.log(m3);

        // 3. 简便形式 针对默认暴露
        // import m3 from "./m3.js";
        // console.log(m3);
    </script>

    <script src="./js/app.js" type="module"></script>
</body>
</html>

app.js

// 入口文件

// 模块引入
import * as m1 from "./m1.js"
import * as m2 from "./m2.js"
import * as m3 from "./m3.js"

2.21 babel对ES6模块化代码转换

npm init --yes 初始化

npm i babel-cli babel-preset-env browserify -D

npx babel src/js -d dist/js --presets=babel-preset-env

npx browserify dist/js/app.js -o dist/bundle.js 打包

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

运行完之后,会多出一个文件夹:
在这里插入图片描述

bundle.js文件里面就是转化之后的ES5代码

打开浏览器,控制台输出跟之前一样
在这里插入图片描述

修改app.js,如下:

// 入口文件

// 模块引入
import * as m1 from "./m1.js"
import * as m2 from "./m2.js"
import * as m3 from "./m3.js"

// console.log(m1);
// console.log(m2);
// console.log(m3);

m1.teach();
m2.findHappy();
m3.default.change();

修改完文件之后,要重新进行打包:

npx babel src/js -d dist/js --presets=babel-preset-env

npx browserify dist/js/app.js -o dist/bundle.js 打包

打开浏览器,查看控制台:
在这里插入图片描述

2.22 ES6模块化引入NPM包

通过jquery包对home.html的背景颜色进行修改

安装jquery包:

npm i jquery

然后重新打包:

npx babel src/js -d dist/js --presets=babel-preset-env

npx browserify dist/js/app.js -o dist/bundle.js

app.js

// 修改背景颜色为粉色
import $ from 'jquery'; // const $ = require("jquery");
$('body').css('background', 'pink');
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值