ES6~ES11新特性:生成器函数,Promise

本次的生成器函数以及promise都是关于异步编程的,如果有对JS异步不明白的小伙伴我建议大家去看我的这篇博客>-<

一.生成器函数

生成器就是一个特殊的函数,用于异步编程

  • 声明和调用

声明方式:function * 函数名( ){ }

        function * add(){
            console.log('111');
        }

正确的调用方法

let a1 = add();
a1.next();

pic1

普通的调用方法在这里是不可以的

函数代码的分隔符 yield

        function * add(){
            console.log('111');
            yield '学生';
            console.log('222');
            yield '老师';
            console.log('333');
            yield '学习';
            console.log('444');
        }

我这里用了三个yield,它们将函数代码分割成四块

pic2

现在我们来调用函数

        let a1 = add();
        a1.next();
        a1.next();
        a1.next();
        a1.next();

因为有yield对代码进行分割,所以我们原本需要调用一次就全部输出的内容我们需要调用四次才能够完全显示

pic3

同时因为它是一个迭代器对象,所以我们可以使用for…of对其进行遍历

        for(let v of add()){
            console.log(v);
        }

我们来看一下结果

pic4

这里我们调用一下next()方法

        function * add(){
            // console.log('111');
            yield '学生';
            // console.log('222');
            yield '老师';
            // console.log('333');
            yield '学习';
            // console.log('444');
        }
        let a1 = add();
        console.log(a1.next())
        console.log(a1.next())
        console.log(a1.next())
        console.log(a1.next())

结果是这样的

pic5

  • 参数传递

我们先创建一个生成器函数

        function * fen(){
            yield 111;
            yield 222;
            yield 333;
        }
        let a = fen();
        console.log(a.next());

其结果是这样的

pic6

我们可以传递参数

function * fen(love){
    console.log(love);
}
let a = fen('no1');
console.log(a.next());

pic7

next方法可以传入实参
下一个next方法传入的实参将作为上一个yield方法的返回值

        function * fen(love){
            console.log(love);    //输出love

            const one = yield 111;
            console.log(one);

            const two = yield 222;
            console.log(two);
            
            const three = yield 333;
            console.log(three);
        }

        let a = fen('no1');

        console.log(a.next());
        console.log(a.next('no2'));
        console.log(a.next('no3'));
        console.log(a.next('no4'));

pic8

注意: 第一次调用next()时传入的值不会使用,只是为了开始执行生成器函数

        function * fen(love){
            console.log(love);     //输出love
 
            const one = yield 111;
            console.log(one);

            const two = yield 222;
            console.log(two);
            
            const three = yield 333;
            console.log(three);
        }

        let a = fen('no1');
        
        console.log(a.next('nox'));
        console.log(a.next('no2'));
        console.log(a.next('no3'));
        console.log(a.next('no4'));

pic9

其结果是一样的

实例

1.代码开始执行1s后控制台输出111, 3s后控制台输出222, 6s后控制台输出333

  • 普通方法
        setTimeout(() => {
            console.log(111);
            setTimeout(() => {
                console.log(222);
                setTimeout(() => {
                    console.log(333);
                },3000);
            },2000);
        },1000);

虽然也会成功执行,但是一旦要求多了就会产生回调地狱,这是不可取的

  • 生成器函数
        function one(){     //输出111的函数
            setTimeout(() => {
                console.log(111)
                a.next();
            },1000)
        }

        function two(){     //输出222的函数
            setTimeout(() => {
                console.log(222)
                a.next();
            },2000)
        }

        function three(){       //输出333的函数
            setTimeout(() => {
                console.log(333)
            },3000)
        }

        function * gen(){       //生成器函数
            yield one();
            yield two();
            yield three();
        }

        let a = gen();
        a.next();

附执行结果的视频链接>-<有需求的小伙伴可以前往B站自行观看

利用生成器函数则不会产生回调地狱

2.模拟获取 用户数据 订单信息 商品数据

  1. 首先我们创建函数
        function getUsers(){
            setTimeout(() => {
                let data = "用户数据"
            },1000)
        }

        function getOrder(){
            setTimeout(() => {
                let data = "订单信息"
            },1000)
        }

        function getGoods(){
            setTimeout(() => {
                let data = "商品数据"
            },1000)
        }
        
        function * gen(){
            yield getUsers();
            yield getOrder();
            yield getGoods();
        }

        let a = gen();
        a.next();
  1. 调用next方法将数据传入yield中,输出它的返回值
        function getUsers(){
            setTimeout(() => {
                let data = "用户数据"
                // 调用next方法,并将数据传入
                a.next(data)
            },1000)
        }

        function getOrder(){
            setTimeout(() => {
                let data = "订单信息"
                a.next(data)
            },1000)
        }

        function getGoods(){
            setTimeout(() => {
                let data = "商品数据"
                a.next(data)
            },1000)
        }

        function * gen(){
            let users = yield getUsers();
            console.log(users);

            let order = yield getOrder();
            console.log(order);

            let goods = yield getGoods();
            console.log(goods);
        }

        let a = gen();
        a.next();

附执行结果的视频链接>-<有需求的小伙伴可以前往B站自行观看

二.Promise

Promise是ES6引入的异步编程的新解决方案

Promise的使用

我们先来实例化一个Promise对象

        const p = new Promise(function(resolve, reject){
        })

它这里有两个参数,我给它们起名为resolve和reject(默认写法,实际上可以起任何名字)

接下来往里面放一个异步函数settimeout

        const p = new Promise(function(resolve, reject){
            setTimeout(function(){
                // resolve代表成功
                let data = '用户数据'
                resolve(data);

                // reject代表失败
                let err = '数据读取失败'
                reject(err);
            }, 1000)
        })

调用一下

        p.then(function(value){     //成功执行此函数
            console.log(value);
        }, function(reason){        //失败执行此函数
            console.log(reason);
        })

要使用的话我们需要调用promise的then方法,该方法中有两个函数,一个成功时执行,一个失败时执行

可以看到我们的结果是这样的

pic10
如果我们把它注掉

        const p = new Promise(function(resolve, reject){
            setTimeout(function(){
                // resolve代表成功
                // let data = '用户数据'
                // resolve(data);

                // reject代表失败
                let err = '数据读取失败'
                reject(err);
            }, 1000)
        })

在调用后结果是这样的

pic11

Promise在这里只是一个简单介绍,整体的使用方法以及过程原理等等我会发在一个新的专栏>-<里,欢迎大家前去阅读。

选集为20,21,22,23,24

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值