es6(三):迭代器,生成器,Promise对象

本文介绍了JavaScript中的迭代器Iterator、生成器Generator以及Promise对象的作用,包括它们如何实现数据遍历、异步操作管理和类的继承。还讨论了async函数的用法,展示了这些技术在实际编程中的应用。
摘要由CSDN通过智能技术生成

一.迭代器Iterator

迭代器是一个能快捷访问数据的接口,通过Symbol.iterator创建迭代器,然后由迭代器方法next方法获取迭代之后的结果.

迭代器就是一个用于遍历数据结构的指针,一种新的遍历机制

  const item = ['one', 'two', 'three']
        console.log(item[Symbol.iterator]);
        //item[Symbol.iterator]返回迭代器   创建新的迭代器
        const ites = item[Symbol.iterator]()
        //通过迭代器调用next方法,返回对象value: "one"和done:false
        console.log(ites.next());//done:返回false时表示遍历可以继续,如果为true表示遍历完成
        console.log(ites.next());
        console.log(ites.next());
        console.log(ites.next());//done:true  value:undefined 表示数组已经遍历完了

二.生成器generator

可以通过yield将函数挂起,使函数不在往下执行;为了改变执行流程提供可能,也为做异步编程提供了方案

与普通函数的区别:

  • function后面和函数名之前有个*
  • 只能在函数内部使用yield表达式让函数挂起

1.yield

Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行

每次遇到yield,函数暂停执行,下一次再从该位置继续向后执行,而return语句不具备位置记忆的功能。一个函数里面,只能执行一次(或者说一个)return语句,但是可以执行多次(或者说多个)yield表达式。正常函数只能返回一个值,因为只能执行一次return;Generator 函数可以返回一系列的值,因为可以有任意多个yield

yield表达式后面的表达式,只有当调用next方法、内部指针指向该语句时才会执行 

遍历器对象的next方法的运行逻辑如下。

(1)遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

(2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield表达式。

(3)如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。

(4)如果该函数没有return语句,则返回的对象的value属性值为undefined

 function* func() {
            yield 2
        }
        let fn = func()//返回遍历器对象  可以调用next()返回yield值
        console.log(fn.next());//done:false  value:2
        console.log(fn.next());//done:true  value:undefined

2.next()

 function* add() {
            console.log('start');
            let x = yield '2'
            console.log('one:' + x);
            let y = yield '3'
            console.log('two:' + y);
            return x + y
        }
        // x,y不是yield返回值,而是使用next()方法,恢复执行yield传入的实参
        let fn = add()
        console.log(fn.next());//done: false value: "2" 恢复yield的执行
        console.log(fn.next(20));//done:false  value:"3"
        console.log(fn.next(30));//done: true  value:50

3.geneartor用处

(1)为不具备Interator接口的对象提供添加接口遍历操作

有点懵........

 //    2.生成迭代器函数
        function* objectEntries() {
            // 获取对象
            const propKeys = Object.keys(obj)
            // 3.通过for of遍历数组  propKey 表示每一个【name age】
            for (const propKey of propKeys) {
                yield [propKey, obj[propKey]]
            }
        }

        const obj = {
            name: 'lalla',
            age: '18'
        }
        // 1.为数组生成迭代器函数 ,提供接口
        obj[Symbol.iterator] = objectEntries//Symbol(Symbol.iterator):  ƒ * objectEntries()
        console.log(obj);

        // 4.迭代器生成后可通过for。。。of遍历
        for (let [key, value] of objectEntries(obj)) {
            console.log(`${key},${value}`);
        }

(2)让异步代码同步化

设置一个页面加载成功1s后关闭分三步:开始加载页面,加载成功,关闭加载页面

若分别写三个函数进行调用,则隐藏函数会比加载完成函数先执行,因为加载完成是一个异步操作

所以这时候可以使用generator迭代器,通过yield暂停函数,在由next方法调用函数

    // 5.迭代器方法
        function* load() {
            loadUI()
            yield showData()
            hideUI()
        }

        // 1.数据开始加载
        function loadUI() {
            console.log('开始加载......');
        }
        //2.加载完成
        function showData() {
            setTimeout(() => {
                console.log('加载完成');
                itload.next()//7.执行hideUI
            }, 1000)
        }

        // 3.结束加载
        function hideUI() {
            console.log('加载结束......');
        }
        // 4.创建迭代器
        let itload = load()
        // 6.执行showData()
        itload.next()

三.Promise对象

Promise相当于一个容器,保存着未来才会结束的事件(异步操作)的结果;各种异步操作都可以由同样方法处理

特点:

(1)对象的状态不受外界影响,处理异步操作三个状态:pending(进行中),resolved(已成功),rejected(已失败)

(2)状态改变就不再变,

    let pro = new Promise(function (resolved, rejected) {
            //执行异步操作
            let res = {
                code: 221,
                data: {
                    name: 'lala'
                },
                error: '错了'
            }
            setTimeout(() => {
                if (res.code === 222) {
                    resolved(res.data)
                } else {
                    rejected(res.error)
                }
            }, 1000)

        })
        console.log(pro);
        //接收当前异步操作完成后返回的结果 then()可以接受第二个回调函数
        pro.then((val) => {
            console.log(val);
        }, (err) => {
            console.log(err);
        })

也可以简化写:

 // timeout为超时函数
        function timeout(ms) {
            return new Promise((resolved, rejected) => {
                setTimeout(() => {
                    resolved('成功了')
                }, ms)
            })

        }
        // 调用上面函数, 然后返回正确时间,2000为传入的ms参数,val为返回的resolved
        timeout(2000).then((val) => {
            console.log(val);
        })

promise好友很多方法,后期学习

四.async用法

使异步操作更方便

async有多种使用方法:

// 函数声明
async function foo() {}

// 函数表达式
const foo = async function () {};

// 对象的方法
let obj = { async foo() {} };
obj.foo().then(...)

// Class 的方法
class Storage {
  constructor() {
    this.cachePromise = caches.open('avatars');
  }

  async getAvatar(name) {
    const cache = await this.cachePromise;
    return cache.match(`/avatars/${name}.jpg`);
  }
}

const storage = new Storage();
storage.getAvatar('jake').then(…);

// 箭头函数
const foo = async () => {};

async函数返回一个 Promise 对象。async函数内部return语句返回的值,会成为then方法回调函数的参数。

async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await

如果await操作成功,就会使用break语句退出循环;如果失败,会被catch语句捕捉,然后进入下一轮循环。

五.class类/继承

ES6类的写法:

constructor()必须在实例化时立即被调用

 class Person {
            // 实例化时立即被调用
            constructor(name, age) {
                this.name = name
                this.age = age
            }
            // 给实例赋值方法
            sayName() {
                return this.name
            }
            sayAge() {
                return this.age
            }

        }
        let p1 = new Person('ww', '18')
        console.log(p1);

类的继承:

使用extends实现继承

  class Animal {
            constructor(name, age) {
                this.name = name
                this.age = age
            }
            sayName() {
                return this.name
            }
            sayAge() {
                return this.age
            }
        }

        // 继承父类属性方法
        class Dogs extends Animal {
            constructor(name, age, color) {
                super(name, age)
                this.color = color
            }
            sayColor() {
                return `${this.name}今年${this.age}岁了,它是${this.color}的`
            }
            // 重写父类方法
            sayName() {
                return this.name + super.sayAge() + this.color
            }
        }

        let d1 = new Dogs('大老黑', '2', 'black')
        console.log(d1.sayColor());
        console.log(d1.sayName());

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值