ES6---学习之旅

参考笔记:ES6开发必备基本用法_牛肉粉面的博客-CSDN博客

参考倔金:ES6常用API详讲 - 掘金

学习视频:01 ES6介绍_哔哩哔哩_bilibili 

相关手写代码:

<!--
 * @Author: kjpkjp 9361167+kjpkjp@user.noreply.gitee.com
 * @Date: 2022-09-09 20:36:34
 * @LastEditors: kjpkjp 9361167+kjpkjp@user.noreply.gitee.com
 * @LastEditTime: 2022-09-12 21:12:09
 * @FilePath: \adminc:\Users\asus\Desktop\train.html
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<!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">
    <script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
    <title>Document</title>
</head>

<body>
    <script>
        let add = function (a, b) {
            return a + b;
        }
        let add1 = (var1, var2) => (var1 + var2)
        console.log(add(5, 6))
        console.log(add(5, 6))
        let getObj = id => {
            return {
                id: id,
                name: 'heihei'
            }
        }
        let getObj1 = id => ({

            id: id,
            name: 'heihei'

        })
        console.log(getObj(1))

        //8.扩展对象的功能
        //8.1方法简写 原来是 let set =function(){}   现在 set(){}
        console.log('8.扩展对象的功能');
        let cart = {
            wheel: 4,
            set(newVal) {
                if (newVal < this.wheel) {
                    throw new Error('轮子太少')
                }
                this.wheel = newVal
            },
            get() {   //取值器
                return this.wheel
            }
        }
        console.log(cart.get())
        cart.set(6)
        //8.2对象的追加属性【属性名】
        const obj = {};
        obj.isshow = true;
        const name = 'aaaa';
        obj[name + 'bbbb'] = 123468;
        console.log(obj);


        //8.3对象的方法 Object.is() ===
        // 对象的方法:
        // is()  和 ===
        // 比较两个值是否严格相等 
        console.log(NaN === NaN);               // false  ,===有缺陷
        //   console.log(Obejct.is(NaN, NaN));       // true 


        //8.4 对象的合并
        // assign()
        //Object.assign(target,obj1,obj2,...)   返回合并之后的新对象
        // 对象的合并
        /* let newObj = Object.assign({}, { a: 1 }, { b: 2 });
         console.log(newObj);                   // {a: 1, b: 2}
         */


        //9 Symbol  独一无二的数据
        let sy1 = Symbol('hello');
        let sy2 = Symbol('hello');
        console.log(sy1 == sy2, 'sy1==sy2');
        console.log(sy1 === sy2);

        // 10  map和set集合  
        //集合中唯一,无重复的值
        let set = new Set()
        console.log(set);
        //10.1 添加元素 add()
        set.add(2);
        set.add('4');
        set.add('4');         // 这个4会被忽略,因为集合表示无重回复值的有序列表
        console.log(set);     // set(2) {2, "4"}
        //10.2 也可以添加数组
        set.add([1, 2, 3]);


        //10.3 删除元素 delete()
        set.delete(2);
        console.log(set);

        //10.4校验某个值是否在 set 中  has()
        console.log(set.has('4'));    // 返回 true

        //10.5 访问集合的长度
        console.log(set.size);

        //10.6 set 转换成 数组
        let set2 = new Set([1, 2, 3, 4]);
        // 使用扩展运算符来转换
        let arr = [...set2];
        console.log(arr);

        //10.7
        let set4 = new WeakSet(), obj5 = {};  //一行写两个定义
        console.log(set4);
        set4.add(obj5)
        obj5 = null;
        console.log(set4)

        //10.8  map键值对
        let map = new Map()
        map.set(['a', [1, 2, 3]], 'hello');
        console.log(map);

        let m = new Map([
            ['a', 1],
            ['b', 2]
        ])
        console.log(m);

        //11 数组
        let list = 'helloww'
        //利用扩展运算符,转换为真正的数组
        console.log([...list]);

        //11.1  copyWithin()
        // 表示将从 3 号位直到数组结束的成员(8,9,10),替换到从 0 号位开始的位置,结果覆盖了原来的 1, 2, 3。

        console.log([1, 2, 3, 8, 9, 10].copyWithin(0, 3)); // [8, 9, 10, 8, 9, 10];
        console.log([1, 2, 3, 8, 9, 10].copyWithin(-2, 3)); // [8, 9, 10, 8, 9, 10];

        //12.遍历器 values(),keys(),entries()
        for (let index of ['a', 'b', 'c'].values()) {
            console.log(index)
        }

        //14迭代器 iterator   迭代器是一个接口,能快捷的访问数据,
        //*通过items[Symbol.iterator]()是个函数,用来创建迭代器
        //迭代器是用于遍历数据结构的指针
        const items = ['one', 'two', 'three']
        console.log(items);
        const iterat = items[Symbol.iterator]()
        console.log(iterat.next());
        //每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,
        //就是返回一个包含value和done两个属性的对象。其中,value属性是当前成员的值,
        //done属性是一个布尔值,表示遍历是否结束。


        //15生成器     主要解决异步操作  
        //使用场景:为不具备interator接口的对象提供便利操纵
        //一是,function关键字与函数名之间有一个星号 * ;二是,函数体内部使用yield表达式 表达式
        function* func() {
            console.log('star');
            yield '暂停一下';
            console.log('第二下star');
            yield '暂停结束'
        }
        //返回一个遍历器对象
        let o = func()
        console.log(o, '15生成器');
        console.log(o.next());
        console.log(o.next());
        //总结:generator函数是分段执行的,yield语句是暂停执行,而next()是恢复执行

        //15.2生成器
        // 生成器函数:function关键字与函数名之间有一个星号 * ;函数体内部使用yield表达式
        function* add3() {
            console.log('start');
            // 这里的 x 不是 yield '2' 的返回值,它是下一个 next()调用恢复执行时传入的参数值
            let x = yield '2';                 // yield 暂停执行标志
            console.log('one:' + x);
            let y = yield '3';                 // yield 暂停执行标志
            console.log('two:' + y);
            return x + y;
        }
        // 返回一个遍历器对象
        let fn = add3()
        // next() 恢复执行标志
        console.log(fn.next());      // start      {value: '2', done: false}
        // 当 next() 传入参数时,该参数就会被当作上一个 ***(上一个 上一个)yield 表达式的返回值 ,即 x = 20, y = 30
        console.log(fn.next(20));    // one:20     {value: '3', done: false}
        console.log(fn.next(30));    // two:30     {value: '50', done: true}

        //15.3 生成器的应用
        const obj3 = {
            name: 'xxiao',
            age: 15
        }
        console.log(obj3, '查看有没有symbol.iteration接口');  //没有这个迭代器接口啊

        //15.4  Generator 生成器函数举例
        function* objectEntries(obj4) {
            // 获取对象的所有 key 保存到数组 [name, age]
            const propKeys = Object.keys(obj4);
            for (const propkey of propKeys) {
                yield [propkey, obj4[propkey]]   //propkey中保存着obj4的键:name和age;obj[propkey]为相对应的值
            }
        }
        const obj4 = {
            name: '牛肉粉',
            age: 18
        }
        // 把 Generator 生成器函数 赋值  给对象的Symbol.iterator属性, 为该对象加上遍历器接口
        obj4[Symbol.iterator] = objectEntries;  //添加遍历接口
        console.log(obj4);
        //for --of 用来遍历生成器
        // objectEntries(obj4) 等价于 obj4[Symbol.iterator](obj4) 
        for (let [key, value] of objectEntries(obj4)) {
            console.log(`${key}:${value}`);
        }

        //16  生成器的应用
        $.ajax({
            url: 'https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976',
            method: 'get',
            success(res) {
                console.log(res);
            }
        })
        //16.1  利用生成器将同步请求变为异步请求
        function* main() {   //生成器定义函数
            let res = yield request('http://d1.weather.com.cn/dingzhi/101230201.html?_=" + DateTime.Now.GetDateTimeToLongTimeStamp()')
            console.log(res);
            //执行后续请求一系列操作
        }
        let ite = main();  //定义生成器指代名称 
        ite.next();
        function request(url) {    //定义request方法
            $.ajax({
                url,
                method: 'get',
                success(res) {
                    ite.next(res);   //c此操作将成功回调返回的结果赋值给main中的res
                }
            })
        }
        //17 promise 的基本使用
        //先定义个promise对像
        let pro = new Promise(function (resolved, rejected) {
            //执行异步操作
            let res = {
                code: 200,
                data: {
                    name: 'xxiao'
                }
            }
            //模拟异步行为
            setTimeout(() => {
                if (res.code === 200) {
                    resolved(res.data)
                }
            }, 1000);
        })
        console.log(pro);
        pro.then((succe) => {    //then中的回调函数专门接受 resolved返回来的值
            console.log(succe);
        })

        //18 自己封装ajax  自己封装getJson方法
        //then里面传了两个回调函数,第一个代表成功之后的回调,第二个代表失败之后的回调,分别代表resolve()和reject()
        console.log('18---------------');
        const getJson = function (url) {
            return new Promise((resolve, reject) => {
                const xhr = new XMLHttpRequest();
                xhr.open('GET', url);
                xhr.onreadystatechange = handler;
                xhr.resposeType = 'json';
                xhr.setRequestHeader('Accept', 'application/json');
                xhr.send();
                function handler() {
                    if (this.readyState === 4) {
                        if (this.status === 200) {
                            resolve(this.respose);
                        } else {
                            reject(new Error(this.statusText))
                        }
                    }
                }

            })

        }

        getJson('https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976')
            .then((data) => {
                //then里面传了两个回调函数,第一个代表成功之后的回调,第二个代表失败之后的回调,分别代表resolve()和reject()
                console.log(data);    //data相当于promise中成功执行之后返回的resolve中的返回值
            }, (error) => {
                console.log(error);
            })

        //19 promise 的其他方法 resolve 能将现有的任何对象转换为promise对象
        let p = Promise.resolve('成功值')
        //等价于let p = new Promise(resolve=>resolve('foo'))
        p.then(val => {
            console.log(val, '19---------');  //输出成功值 19---------
        })


        //19.1promise 的all() 方法 一般用于游戏共同资源的请求
        let pro1 = new Promise((resolve, reject) => { });
        let pro2 = new Promise((resolve, reject) => { });
        let pro3 = new Promise((resolve, reject) => { });

        let pAll = Promise.all([pro1, pro2, pro3]);
        pAll.then(() => {
            // 三个都成功 才成功
        }).catch(err => {
            // 如果一个失败 则失败
        })



        //19.2小应用  race()的应用  race某个异步请求设置超时时间,并且在超时后执行响应的操作
        // 请求图片资源
        function requestImg(imgSrc) {
            return new Promise((resolve, reject) => {
                const img = new Image();
                // 加载图片资源
                img.onload = function () {
                    resolve(img);
                }
                img.src = imgSrc;
            });
        }
        //延时函数,用于给请求计时
        function timeout() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    reject(new Error('图片请求超时'));
                }, 3000);
            });
        }
        // Promise.race()接受一个包含多个promise对象的数组(数组数组),只要有一个完成,就执行success
        // 如果3s 之内加载完成就执行 then 方法, 3s 之后还没加载完成就执行 catch 方法
        Promise.race([requestImg('https://i2.hdslb.com/bfs/face/59a2cb990fde5e2cd289c3305450664b462da341.jpg@240w_240h_1c_1s.webp'), timeout()]).then((data) => {
            console.log(data);
            document.body.appendChild(data);
        }).catch((err) => {
            console.log(err);
        });

        //20  
        //20.1 async的应用  使异步操作更加方便
        //基本操作 async 她会返回一个promise对像可以调用 太狠 catch

        async function funcc() {
            let s = await 'hello';
            let data = await s.split('');
            return data;  //这个return 是等待完所有的await之后才执行的
        }
        //如果 async 函数中有多个 await , 那么 then 函数 会等待所有的 await 指令运行完才去执行
        funcc().then(v => { console.log(v, '这是20节的内容async'); }).catch(err => { console.log(err); })

        //20.2
        async function f2() {
            //  throw new Error('20出错了');
            await Promise.reject('出错了');
            await Promise.resolve('hello');
        }
        f2().then(v => { console.log(v, '这是20节的内容async'); }).catch(err => { console.log(err); })// 返回  出错了
        //针对上诉遇到 reject状态,就中断执行的问题,可以通过 try...catch 代码块解决


        //20  .3 需求 获取天气  现在 now的数据
        /* 获取天气接口  ajax请求*/
        const getJson2 = function (url) {
            return new Promise((resolve, reject) => {
                const xhr = new XMLHttpRequest();
                xhr.open('GET', url);
                xhr.onreadystatechange = handler;
                xhr.resposeType = 'json';
                xhr.setRequestHeader('Accept', 'application/json');
                xhr.send();
                function handler() {
                    if (this.readyState === 4) {
                        if (this.status === 200) {
                            resolve(this.respose);
                        } else {
                            reject(new Error('获取天气出错'))
                        }
                    }
                }

            })

        }
        /* 定义 getNowWeather 函数  异步获取  天气请求的返回值*/
        async function getNowWeather(url) {
            let result = await getJson2(url);
            console.log(result, 'result');
            let arr = await result.HeWeather6;
            return arr[0].now;
        }

        /* 获取天气调用 */
        getNowWeather('https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976').then(now => {
            console.log(now, '20.3获取天气');
        }).catch(err => {
            console.log(err);    //这个err返回相当于上面的《=》 reject(new Error('获取天气出错'))
        })



        //21  类
        console.log('21======================');
        //21.1    es5 d的构造类  看起来像个函数
        function Person(name, age) {
            this.name = name;
            this.age = age;
        }
        //构造函数指向原型prototype    =====创建原型中的方法
             Person.prototype.sayName = function () {
                  return this.name;
              } 
        let pick = new Person('************************xx小小怪', 18);
        console.log(pick);
       console.log(pick.sayName());  



        // 21.2  es6的构造函数
        // es6
        console.log('es6中的构造函数的写法');
        class Kerson {
            // 实例化的时候会立即被调用
            constructor(name, age) {
                this.name = name;
                this.age = age;
            }
            //等同于Person.prototype = function sayName(){}
            sayName() {
                return this.name;
            }
            sayAge() {
                return this.age;
            }
        }
        // 小技巧:通过 Objec.assign() 方法(详见对象的扩展功能)一次性向类中添加多个方法
        /*  给原型上添加方法  用Object.assign()方法
        Object.assign(Person.prototype, {
            sayName(){
                return this.name;
            }
            sayAge(){
                return this.age;
            }
        })
        */

        let p4 = new Kerson('牛肉粉', 18);
        console.log(p4);
        p4.sayName();


        //22继承   建议重听了解  super  和。call(this指向)
        class Animal {
            // 实例化的时候会立即被调用
            constructor(name, age) {
                this.name = name;
                this.age = age;
            }
            sayName() {
                return this.name;
            }
            sayAge() {
                return this.age;
            }
        }
        //这儿super注意点
        class Dog extends Animal {
            constructor(name, age, color) {
                // 如果 子类 继承了 父类,且 子类 中写了构造器,则 子类 构造器的 super 必须要调用
                super(name, age);  //会调用父类的构造函数,直接执行zhij 等同于 Animal.call(this,name,age); 继承父类的属性******this指向这儿指向Dog
                this.color = color;
            }
            // 子类自己的方法
            sayColor() {
                return `${this.name}是${this.age}岁了,它的颜色是${this.color}`;
            }
            // 重写父类的方法
            sayName() {
                //***** super 相同于 Animal.prototype   
                return this.name + super.sayAge + this.color;
            }
        }

        let d1 = new Dog('小黄', 28, 'red');
        console.log(d1.sayAge());     // 调用继承父类的方法
        console.log(d1.sayColor());   // 调用子类自己的方法
        console.log(d1.sayName());    // 调用重写父类的方法
    </script>
</body>

</html>

 2. let 和 const 的补充

// 例 1
// 底层看到 var ,会自动在前面声明变量,即变量提升,而 let 不会
// 如下代码,会在前面 自动添加 var a; 而不会自动添加 let b;
let a = 10;
var b = 1;
console.log(a)  // ReferenceError: a is not defined.   报错
console.log(b)  // 1
 
 
 
// 例 2
var a = [];
// 由于变量提升,会在这里自动声明 var = i;
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6]();         //  10   由于变量提升,var i 最后访问到循环十次之后的结果
 
// let 是一个块作用域,let声明的变量只在它所在的代码块有效。
for (let i = 0; i < 10; i++) {
  // ...
}
console.log(i);  // ReferenceError: i is not defined
 
var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6]();          // 6  因为这儿定义的是let

 
 
// 例 3
// var 的重复声明
var c = 1;
var c = 3;
console.log(c);    //4 
 
//let 不可以重复声明
let d = 1;
let d = 3;
console.log(d);    //报错
 
 
 
// 例 4
//const 声明常量,一旦声明就不能被修改
const max = 30;
max = 40;
console.log(max);   //会报错

//修改常量 对象
const person={
    name='lisi'
}
person.name='kkk'

 

 4. 函数默认值和剩余参数(补充)

argument就是未知函数有多少参数的时候用 的(函数本身有的属性/方法 )

打印argument(重复3次)

输出:

下图为打印函数中的所有参数(从1开始)

 输出:

下图为取出对象中指定的属性的函数pick(): pick中的'title','year'为你要取出的属性名是什么

  • 剩余参数
  • 由...和一个紧跟着的具名参数组成 : ...keys           *****keys可以是任意单词
  • ...keys 解决了 arguments 的问题 
  • 剩余参数必须放在最后
  • log(keys)     *************为一个数 组


5.扩展运算符(补充)

apply应用

对于Math.max 参数里面不支持Math.max([param1,param2]) 也就是数组
但是它支持Math.max(param1,param2,param3…),所以可以根据刚才apply的那个特点来解决
ES5 写法:::::::::::::::::::::::::::::;::::::::var max=Math.max.apply(null,array),这样轻易的可以得到一个数组中最大的一项
(apply会将一个数组装换为一个参数接一个参数的传递给方法)
第一个参数为什么是null:
这块在调用的时候第一个参数给了一个null,这个是因为没有对象去调用这个方法,
我只需要用这个方法帮我运算,得到返回的结果就行,.所以直接传递了一个null过去


6.箭头函数和this指向的注意事项

        let getObj=id =>{
            return{
                id:id,
                name:'heihei'
            }
        }
简洁版:
        let getObj1=id =>({
        
                id:id,
                name:'heihei'
            
        })
变为({})用于输出对象

箭头函数没有this的指向,箭头函数内部的this值只能通过查找作用域链来确定。this函数作用域内,逐级往上找。(一旦使用箭头函数,当前不存在作用域链)

// 如果箭头函数被一个非箭头函数所包括,那么this的值与该函数的所属对象相等,否则是全局的window对象(按作用域往上找当前对象)

下图会报错,因为这个this的指向为window全局对象 

 注意:使用箭头函数,函数内就没有argument参数(因为没有作用域链)

  • 箭头函数不能使用 new 关键字来实例化对象,function 函数也是一个对象,但是箭头函数不是一个对象,它就是一个表达式。
  • 报错

 7. 解构赋值(两边类型要相同)

完全解构:

 不完全解构:剩余运算符

 默认值解构和数组解构::注意两边的对象类型要相同

9. Symbol类型

如何获取声明的Symbol类型的数据,下面为两种方法,一般不调用(了解即可) 

10. Map 和 Set 方法

weakSet的详细参考博客:WeakSet的使用_mb5fdb0f269f12c的技术博客_51CTO博客 

map的用法:
let map = new Map();
// set() 设置值
map.set('name', '张三');
map.set('age', '20');
console.log(map);           // 输出 { 'name' => '张三', 'age' => '20'}
// 键和值可以是任意类型
map.set(['a', [1, 2, 3]], 'hello');
 
// get() 获取值
console.log(map.get('name'));     //张三
 
// has()  校验某个值是否在 map 中
console.log(map.has('name'));     //true
 
// delete()  删除值
map.delete('name');
 
// clear()  清除所有值
map.clear();

 

上图输出结果:

11. 数组的扩展方法 

JavaScript 中 call()、apply()、bind() 的用法 | 菜鸟教程

// Array.from()方法用于将伪数组转为真正的数组
function add() {
// ES5 的写法,不宜阅读
var arr1 = [].slice.call(argumets); // [1, 2, 3]
console.log(arr1);
// ES6 的写法
let arr2 = Array.from(argumets); // [1, 2, 3]
console.log(arr2);
}
add(1, 2, 3);
 
 
// 方法二:使用扩展运算符, 将伪数组转为真正的数组
// querySelectorAll()方法返回的是一个类似数组的对象
let lis = document.querySelectorAll('li');   
console.log([...lis]);
 
// Array.from()方法还可以接受第二个参数,对每个元素进行处理
let lis = document.querySelectorAll('li'); 
let names2 = Array.from(lis, s => s.textContent);
console.log(names2);

上述代码的返回结果:   

for of 循环_KeplerMartin的博客-CSDN博客_for of循环 -----------Es6中的一些for循环区别

 14 Iterator(遍历器)

 15.生成器

  //15生成器     主要解决异步操作  
        //使用场景:为不具备interator接口的对象提供便利操纵
        //一是,function关键字与函数名之间有一个星号 * ;二是,函数体内部使用yield表达式 表达式
        function* func() {
            console.log('star');
            yield '暂停一下';
            console.log('第二下star');
            yield '暂停结束'
        }
        //返回一个遍历器对象
        let o = func()
        console.log(o, '15生成器');
        console.log(o.next());
        console.log(o.next());
        //总结:generator函数是分段执行的,yield语句是暂停执行,而next()是恢复执行

        //15.2生成器
        // 生成器函数:function关键字与函数名之间有一个星号 * ;函数体内部使用yield表达式
        function* add3() {
            console.log('start');
            // 这里的 x 不是 yield '2' 的返回值,它是下一个 next()调用恢复执行时传入的参数值
            let x = yield '2';                 // yield 暂停执行标志
            console.log('one:' + x);
            let y = yield '3';                 // yield 暂停执行标志
            console.log('two:' + y);
            return x + y;
        }
        // 返回一个遍历器对象
        let fn = add3()
        // next() 恢复执行标志
        console.log(fn.next());      // start      {value: '2', done: false}
        // 当 next() 传入参数时,该参数就会被当作上一个 ***(上一个 上一个)yield 表达式的返回值 ,即 x = 20, y = 30
        console.log(fn.next(20));    // one:20     {value: '3', done: false}
        console.log(fn.next(30));    // two:30     {value: '50', done: true}

        //15.3 生成器的应用
        const obj3 = {
            name: 'xxiao',
            age: 15
        }
        console.log(obj3, '查看有没有symbol.iteration接口');  //没有这个迭代器接口啊

        //15.4  Generator 生成器函数举例
        function* objectEntries(obj4) {
            // 获取对象的所有 key 保存到数组 [name, age]
            const propKeys = Object.keys(obj4);
            for (const propkey of propKeys) {
                yield [propkey, obj4[propkey]]   //propkey中保存着obj4的键:name和age;obj[propkey]为相对应的值
            }
        }
        const obj4 = {
            name: '牛肉粉',
            age: 18
        }
        // 把 Generator 生成器函数赋值给对象的Symbol.iterator属性, 为该对象加上遍历器接口
        obj4[Symbol.iterator] = objectEntries;
        console.log(obj4);
        // objectEntries(obj4) 等价于 obj4[Symbol.iterator](obj4) 
        for(let [key,value] of objectEntries(obj4)){
            console.log(`${key}:${value}`);
        }

16 生成器应用

  $.ajax({
            url:'https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976',
            method:'get',
            success(res){
                console.log(res);
            }
         }) 
         //16.1  利用生成器将同步请求变为异步请求
         function *main(){   //生成器定义函数
            let res = yield  request('http://d1.weather.com.cn/dingzhi/101230201.html?_=" + DateTime.Now.GetDateTimeToLongTimeStamp()')
            console.log(res);
            //执行后续请求一系列操作
         }
         let ite=main();  //定义生成器指代名称 
         ite.next();
         function request(url){    //定义request方法
            $.ajax({
                url,
                method:'get',
                success(res){
                   ite.next(res);   //c此操作将成功回调返回的结果赋值给main中的res
                }
            })
         }

17 promise

  • 简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果
  • Promise 是一个对象,Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。axios 的内部实现原理就是通过 Promise 实现的
  • Promise对象有以下两个特点:
  • 对象的状态不受外界影响。有三种状态:pending(进行中)、fulfilled(成功)和rejected(失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态
  • 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为resolved和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果
  • Promise对象是一个构造函数,用来生成Promise实例,带有一个回调函数,回调函数的两个参数是 resolve(成功) 和 reject(失败),这两个参数他们也是函数。
  • then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,它们都是可选的。

### 实例化
    Promise构造函数接收一个函数作为参数,也就是回调函数;该函数的两个参数分别是resolve和reject。resolve作为成功的回调函数,reject作为失败的回调函数。Promise对象代表一个异步操作有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。最后返回resolved(已定型)结果。
### 2.实例方法
    定义在Promise.prototype中的方法,通过Promise实例可以直接调用
    then() 状态由pending变为fulfilled的时候也就是异步操作成功之后执行该回调函数
        参数:回调函数,回调函数的参数为resolve函数传递过来的值
        返回值:返回一个新的Promise实例对象,因此可以使用链式调用
    catch() 由pending变为rejected的时候执行该回调函数也就是异步失败之后执行该回调函数
        参数:回调函数,回调函数的参数为reject函数传递过来的值
        返回值:返回一个新的Promise实例对象,因此可以使用链式调用
    finally()无论异步操作执行成功失败与否,都会执行该回调
        参数:回调函数
        返回值:返回一个新的Promise实例对象 

 18-19  all(), race()

//18 自己封装ajax  自己封装getJson方法
        //then里面传了两个回调函数,第一个代表成功之后的回调,第二个代表失败之后的回调,分别代表resolve()和reject()
        console.log('18---------------');
        const getJson = function (url) {
            return new Promise((resolve, reject) => {
                const xhr = new XMLHttpRequest();
                xhr.open('GET', url);
                xhr.onreadystatechange = handler;
                xhr.resposeType = 'json';
                xhr.setRequestHeader('Accept', 'application/json');
                xhr.send();
                function handler() {
                    if (this.readyState === 4) {
                        if (this.status === 200) {
                            resolve(this.respose);
                        } else {
                            reject(new Error(this.statusText))
                        }
                    }
                }

            })

        }

        getJson('https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976')
            .then((data) => {
                //then里面传了两个回调函数,第一个代表成功之后的回调,第二个代表失败之后的回调,分别代表resolve()和reject()
                console.log(data);    //data相当于promise中成功执行之后返回的resolve中的返回值
            }, (error) => {
                console.log(error);
            })

        //19 promise 的其他方法 resolve 能将现有的任何对象转换为promise对象
        let p = Promise.resolve('成功值')
        //等价于let p = new Promise(resolve=>resolve('foo'))
        p.then(val => {
            console.log(val, '19---------');  //输出成功值 19---------
        })



        //小应用  race()的应用
        // 请求图片资源
        function requestImg(imgSrc) {
            return new Promise((resolve, reject) => {
                const img = new Image();
                // 加载图片资源
                img.onload = function () {
                    resolve(img);
                }
                img.src = imgSrc;
            });
        }
        //延时函数,用于给请求计时
        function timeout() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    reject(new Error('图片请求超时'));
                }, 3000);
            });
        }
        // Promise.race()接受一个包含多个promise对象的数组(数组数组),只要有一个完成,就执行success
        // 如果3s 之内加载完成就执行 then 方法, 3s 之后还没加载完成就执行 catch 方法
        Promise.race([requestImg('https://i2.hdslb.com/bfs/face/59a2cb990fde5e2cd289c3305450664b462da341.jpg@240w_240h_1c_1s.webp'), timeout()]).then((data) => {
            console.log(data);
            document.body.appendChild(data);
        }).catch((err) => {
            console.log(err);
        }); 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值