es6 生成器和Promise(es6学习笔记04)

前言:本篇主要记下生成器和Promise

一、生成器

生成器其实就是一个特殊的函数。

生成器函数:是es6提供的一种**异步编程**解决方案,语法行为与传统函数完全不同。

异步编程:简单来说就是纯回调函数,例如node、fs、ajax、MongoDB等

1.1生成器的声明

在函数名前面加*

//声明特殊
function * hong(){
    
    
     console.log("你好,红红"); //并不会直接输出
}
//执行特殊
let iterator = hong();
terator.next();  //调用.next才会输出“你好,红红”(迭代器)

在这里插入图片描述

:执行语句直接调用不会执行,要通过.next方法去调用

1.2函数代码分隔符—yield

把函数内部分割成一段一段的

//函数代码的分隔符 yield的使用
function *lv(){
    
    
    console.log(111);
    yield '我分隔';
    console.log(222);
    yield '我分隔,到我停止';
    console.log(333);
    yield '我再分隔';
    console.log(444);
}
let lvtor = lv();
lvtor.next();    //调用一次,输出111
lvtor.next();    //接着调用,接着输出222
lvtor.next();    //接着调用,接着输出333
//console.log(lvtor.next());  执行获取迭代器的对象

//遍历
for(let v of lv()) {
    
    
     console.log(v);
}

以上分隔结果
在这里插入图片描述

遍历结果

在这里插入图片描述

1.3 生成器函数的参数传递

next的参数作为前一个yield语句的返回值

//生成器函数的传参
function * mini(arg){
    
    
     console.log(arg);
     let one = yield 111;
     console.log(one);
     let two = yield 222;
     console.log(two);
     let three = yield 333;
     console.log(three);
}

let itor = mini('AAA');
console.log(itor.next());
//next方法可以传入实参
console.log(itor.next('BBB')); //为yield111传入参数
console.log(itor.next('CCC'));
console.log(itor.next('DDD'));

输出结果:
在这里插入图片描述

1.4 生成器小例子

(1)间歇调用

1s后输出111, 然后2s后输出222 ,然后3s后输出333

//用生成器实现
        function one(){
    
    
            setTimeout(() => {
    
    
                console.log(111);
                it.next();   //使其继续执行下一个
            },1000)
        }
        function two(){
    
    
            setTimeout(() =>{
    
    
                console.log(222);
                it.next();
            },2000)
        }
        function three(){
    
    
            setTimeout(()=>{
    
    
                console.log(333);
                it.next();
            },3000)
        }

        function * green(){
    
    
            yield one();
            yield two();
            yield three();
        }
        //调用
        let it = green();
        it.next();
(2)模拟数据的获取

首先得先获取用户信息,再根据用户信息获取订单数据,接着再根据订单数据获取商品数据,由于他们是一层层获取的关系,所以可以用生成器来实现。

//模拟获取 用户数据 订单信息 商品数据
        function getUser(){
    
    
            setTimeout(()=>{
    
    
                let data = '用户信息';
                //调用next方法,并将数据传入
                getor.next(data);
            },1000)
        }
        function getOrder(){
    
    
            setTimeout(()=>{
    
    
                let data = '订单数据'
            },1000)
        }
        function getGoods(){
    
    
            setTimeout(()=>{
    
    
                let data = '商品数据'
            },1000)
        }
        //定义生成器函数
        function *datas(){
    
    
            yield getUser();
            yield getOrder();
            yield getGoods();
        }
        //调用生成器函数
        let getor = datas();
        getor.next();
  • 使用到了next方法传递参数。

二、Promise

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

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

当异步进程很多的时候,promise可以用来减少缩进。

2.1Promise的then方法的使用

  • 如果状态是成功的,则调用then的第一个回调函数,否则调用第二个。
//实例化 Promise对象
const h = new Promise(function(resolve,reject){
    
       //这里定义的两个参数一般是这两个,潜规则
setTimeout(function(){
    
    
       let data = '数据读取成功啦';
       resolve(data);  //调用resolve,表示读取成功

        //let err = '数据读取失败了';  调用reject,表示读取失败
        //reject(err);
     },1000)
 });

//调用promise 对象的then方法
h.then(function(value){
    
    
      console.log(value);    //成功时执行
},function(reason){
    
    
      console.error(reason);  //失败时执行
})

调用then方法,then方法的返回结果是 Promise对象,对象状态由回调函数的执行结果决定

  1. 如果回调函数中返回的结果是 非 Promise类型的属性(包括没有返回值的情况undefined),状态为成功,返回值为对象的成功的值。
  2. 是Promise对象,则返回对象的内容
  3. 抛出错误
//then 方法解析
        const hh = new Promise((resolve,reject) =>{
    
    
            setTimeout(()=>{
    
    
                resolve('红红的数据');
                //reject('出错啦');
            },1000)
        });
        
        const result = hh.then(value =>{
    
    
            console.log(value);
            //1.非Promise类型的属性
            //return 'hhhhhh';
            //2.是promise对象
            //return new Promise((resolve,reject)=>{
    
    
                //resolve('ok');
                //reject('error');
            //});
            //3.抛出错误
            throw new Error('出错了');
        },reason =>{
    
    
            console.warn(reason);
        });
  • 如果then的返回结果是Promise,则可以使用链式调用
p.then(value =>{
    
    },reason=>{
    
    }).then(value=>{
    
    },reason=>{
    
    })

2.2 用Promise封装读取文件

下面是写在名为Promise读取文件.js中:

//1.引入 fs 模块
const fs = require('fs');

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

//3.使用Promise封装
const p = new Promise(function(resolve,reject){
    
    
    fs.readFile("./data/study.md",(err,data)=>{
    
    
        //判断如果失败
        if(err) reject(err);
        //如果成功
        resolve(data);
    });
});
//调用then方法
p.then(function(value){
    
    
    console.log(value.toString());
},function(reason){
    
    
    console.log("读取失败啦!");
});
  • 在控制台输入 node Promise读取文件.js就可以查看结果了。

2.3用Promise封装ajax

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <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((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.log(reason);
    });
    </script>
</body>
</html>

2.4Promise实现多个文件内容的读取

//引入fs
const fs = require("fs");

const h = new Promise((resolve,reject)=>{
    
    
    fs.readFile("./data/study.md",(err,data)=>{
    
    
        resolve(data);
    });
});
//调用
h.then(value =>{
    
    
    return new Promise((resolve,reject)=>{
    
    
        fs.readFile('./data/红红.md',(err,data)=>{
    
    
            resolve([value,data]);
        });
    })
}).then(value => {
    
    
    return new Promise((resolve,reject)=>{
    
    
        fs.readFile('./data/绿绿.md',(err,data)=>{
    
    
            //压入
            value.push(data);
            resolve(value);
        });
    })
}).then(value =>{
    
    
    console.log(value.join('\r\n'));
});

结果:

在这里插入图片描述

2.5Promise的catch方法

算是then方法的语法糖,用来设置失败的回调

p.catch(function(reason){
    
    
    console.warn(reason);
});

猜你喜欢

转载自blog.csdn.net/weixin_48931875/article/details/113528068