ES6学习笔记(第二天)

ES6学习笔记(第二天)

1.迭代器

迭代器(lterator)是一种接口,为各种不同的数据结果提供统一的访问机制,只要部署了lterator接口,就可以完成遍历操作,es6创造一种新的遍历方式:for…of
原生具备iterator的数据(可以用for…of循环)有:
Array
Argunments
Set
Map
String
TypedArray
NodeList
事例:

 var data=['wwh','wxh','cxj']
 for(let i in data){
    console.log(i)//输出0,1,2
 }
 for(let i of data){
    console.log(i)//输出wwh,wxh,cxj
 }
 //in对应key,of对应value,在对象中也可以这样用

工作原理:

官方:
先创建一个指针对象,指向当前数据结构的起始位置
第一次调用对象的next方法,指针自动指向数据结构的第一个成员
接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
每次调用next方法就会返回一个包含value和done属性(是否完成)的对象

自己的理解:
使用data数组里面的Symbol(Symbol.iterator): ƒ values() 这个函数创建了一个对象,这个对象里面的next方法一直访问data里面对应的key/value,每次返回的都是一个对象,里面包含value和done两个属性,访问完后返回value:undefined的对象

事例:

 let d=data[Symbol.iterator]()//通过[]调用属性,与.一致,Symbol.iterator是一个属性,这个属性里面是一个函数,最后用()调用这个函数,创建了一个对象
 console.log(d)//查看这个对象,里面有一个next()方法
 console.log(d.next());//{value: 'wwh', done: false}
 console.log(d.next());//{value: 'wxh', done: false}
 console.log(d.next());//{value: 'cxj', done: false}
 console.log(d.next());//{value: undefined, done:true}

迭代器的应用:自定义遍历方法

案例:
定义一个遍历方法,可以遍历一个对象中数组的所有成员。

//声明一个对象
const data={
    name:'airen',
    lis:[
        'wwh',
        'wxh',
        'cxj'
    ],
    //自己给某些结构加上iterator接口
    [Symbol.iterator](){
        //索引变量
        let index=0;
        //没有这行,this指向return的那个对象,相当于把this的作用域往上提了一层
        let _this=this;
        return {//返回一个指针对象,即创建一个指针对象
            next:function(){ //创建对象的next方法
                // 返回一个包含value和done属性(是否完成)的对象
                if(index<_this.lis.length){
                    const result= {value:_this.lis[index],done:false};
                    index++;
                    return result;
                }else{                   
                    return {value:undefined,done:true};
                }
            }
        };
    }
}
//自定义遍历这个对象
for(let v of data){
    console.log(v);
}
console.log('--------------------')
console.log(data);
// 输出结果
// wwh
//  wxh
//  cxj
//  --------------------
 
// {name: 'airen', lis: Array(3), Symbol(Symbol。iterator): ƒ}
// lis: (3) ['wwh', 'wxh', 'cxj']
// name: "airen"
// Symbol(Symbol.iterator): ƒ [Symbol.iterator]()
// [[Prototype]]: Object

2.生成器

生成器就是一个特殊的函数,是异步编程新的解决方案。它的结构不是直接输出,而是要通过next()来控制

//定义方式 *
function * fun(){
    console.log('wwh');
}
let a=fun();
// console.log(a);//输出一个迭代器对象(有next方法)
a.next();//输出wwh
 function * fun(){
    console.log('wwh');
    //yield 分割代码块,一个可以分为两个
    yield '暂停';
    console.log('wxh');
    yield '暂停';
    console.log('cxj');
}
let a=fun();
console.log(a);//输出一个迭代器对象(有next方法)
a.next();//输出wwh  
a.next();//输出wxh
a.next();//输出cxj

//利用for...of可以输出yield的内容
for(let v of fun()){
    console.log(v)
}
// 输出内容:
// wwh
// 暂停 
// wxh
// 暂停 
// cxj

//原因:
// yield后面自定义的值在next返回对象的value里面

生成器函数的参数传递

function * fun(arg){
    console.log(arg);//输出aaa
    let one=yield 111;
    console.log(one);//输出bbb
    let two=yield 222;
    console.log(two);//输出ccc
    let three=yield 333;
    console.log(three);//输出ddd
}
let a=fun('aaa');
console.log(a.next());//第一次调用next
//next方法可以传入实参
//第二次调用next的实参将作为第一个yield的整体返回结果
console.log(a.next('bbb'))//输出{value: 222, done: false}
console.log(a.next('ccc'))
console.log(a.next('ddd'))

作为异步编程的新方法

//需求:1s后输出111,2s后输出222,3s后输出333
//第一种实现方式:

// setTimeout(() => {
//     console.log(111);
//     setTimeout(() => {
//         console.log(222);
//         setTimeout(() => {
//             console.log(333);  //如果有很多个的化会一直推进,可能会超出显示器范围,不好维护和操作
//         }, 3000);
//     }, 2000);
// }, 1000);

// 第二种实现方式:
function one(){
    setTimeout(()=>{
        console.log(111);
        a.next();       //定时器运行完调用下一个,实现了异步编程
                        //不会推进,一直是这样的往下一列,方便观看和操作、维护
    },1000)
}
function two(){
    setTimeout(()=>{
        console.log(222);
        a.next();
    },2000)
}
function three(){
    setTimeout(()=>{
        console.log(333);
        a.next();
    },3000)
}
function *fun(){
    yield one();
    yield two();
    yield three();
}
//调用生成器函数
let a=fun();
a.next();

练习:
需求:模拟获取,分别一秒后打印出用户信息、订单信息、商品信息

    function getuser(){
        setTimeout(()=>{
            let data='用户信息'     //一定要有延时器否则会报错
            it.next(data)          //第二个调用的next(),它的实参会被当成第一个yield的返回值
        },1000)
        
    }
    function getorder(){
        setTimeout(()=>{   
            let data='订单信息'
            it.next(data)          //第三个调用的next(),它的实参会被当成第二个yield的返回值
    },1000)
     
    }
    function getgoods(){
        setTimeout(()=>{
            let data='商品信息'
            it.next(data)          //第四个调用的next(),它的实参会被当成第三个yield的返回值
        },1000)
        
    }
    
    function * get(){
        let user=yield getuser();
        console.log(user);
        let order=yield getorder();
        console.log(order);
        let good=yield getgoods();
        console.log(good);
    }

    let it=get() //返回一个对象,用it接受
    it.next() //it属性里有一个next(),第一个调用的next()

3.Promise

它是es6中异步编程的新的解决方案。相当于一个构造函数、

    //实例化Promise对象
    //对象的状态只有三种初始化、成功、失败
    const p= new Promise((resolve,reject)=>{
        //如果成功获取数据,就调用resolve
        let data='数据库中的数据';
        resolve(data); //p状态变为成功
        //如果失败就调用reject
        let err='数据库读取失败';
        reject(err);//p状态变为失败
    })


p.then(//调用then方法
    function(value){//p状态变为成功后then会调用第一个回调函数
        console.log(value);
    },function(err){//p状态变为失败后then会调用第二个回调函数
        console.log(err);
    }
)

事例:读取同级目录下的wenjian.md里面的内容(道阻且长,不行不至。)

//利用node.js的fs模块进行文件操作,演示promise
//这是之前的做法
const fs =require('fs')
fs.readFile('./wenjian.md',(err,data)=>{
    if(err) throw err
    console.log(data.toString());
})

//这是现在的做法
 const p= new Promise((resolve,reject)=>{
    
    fs.readFile('./wenjian.md',(err,data)=>{ 
    //如果失败就调用reject
    if(err) throw reject(err)
     //如果成功获取数据,就调用resolve
    resolve(data);
    })
})


p.then(//调用then方法
    function(value){//p状态变为成功后then会调用第一个回调函数
                //利用toString()转化buffer为字符串
        console.log(value.toString());
    },function(err){//p状态变为失败后then会调用第二个回调函数
        console.error(err);//红色报错
    }
)

Promise.prototype.then

    const p= new Promise((resolve,reject)=>{
        //如果成功获取数据,就调用resolve
        let data='数据库中的数据';
        resolve(data); //p状态变为成功
        //如果失败就调用reject
        let err='数据库读取失败';
        reject(err);//p状态变为失败
    })


const result=p.then(//调用then方法
    function(value){//p状态变为成功后then会调用第一个回调函数
        console.log(value);
        //1.非promise
        //return 123,result里面的值就是123
        //2.promise
        //return 123,result里面的值就是123
    },function(err){//p状态变为失败后then会调用第二个回调函数
        console.warn(err);//黄色警告
    }
)
console.log(result)//then返回的也是一个promise的对象
// 对象状态由then函数的执行结果决定
//1.返回的是非promise类型的数据,则result对象状态为成功,且对象的value就是then函数返回的值;
//2. 如果是promise对象,则result状态由返回的promise对象的状态决定,值同上

catch方法
用来指定promise对象失败的回调

const p=new Promise((resolve,reject)=>{
    //设置p对象的状态为失败,并设置失败的值
    reject('出错了')
})
//这是第一种指定失败的方法:用then的第二个函数
// p.then(function(value){},function(reason){
//     console.error(reason)
// })

//第二种:用catch方法
p.catch(function(reason){
    console.error(reason)
})

es6中的promise就学到这里,详细请看专门的promise教程。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值