初学Promise

        对于这个概念,是一位朋友无意间提给我的,他问了我一个问题:如果你要同时通过Ajax请求数据,然后判断他们数据是否一样,你会怎么做。身为一只菜鸡,我很给面子的说到:分别用Ajax获得数据再进行比较不就好了?看着他意味深长的笑了,我才意识到事情没有这么简单。

        我们来分析一下,通过Ajax请求回来数据的时候,是可能有时间差的,如果你不是全部数据都返回了,就执行判断语句,那肯定会出错的,所以我们必须有个函数,当请求的数据都返回了,再进行比较。这时候就用到了Promise函数。

        Promise是ES6的语法,其实在学习react跟vue的时候,已经体会到ES6确实是提供了很多快捷高效的语法,个人觉得抽空学学还是很有必要的。

        我学习Promise主要是通过大神们的博客再自己敲敲学到的。其中参考了http://www.hangge.com/blog/cache/detail_1638.html。通过博主的例子,初次体会到了Promise用法。接下来我来讲一下我所学到的Promise。

 

Promise(function(resolve,reject){})

        其中resolve和reject是两个回调方法,什么是回调方法呢,回调方法就是将一个方法func2作为参数传入另一个方法func1中,当func1执行到某一步或者满足某种条件的时候才执行传入的参数func2。现在通过例子来了解下solve和reject。

        var a=1;
        function log(s){
            console.log(s);
        }

        function cook(){
            log("进入cook函数");
            var c=new Promise(function(resolve,reject){
                if(a==1){
                    resolve(log("在cook的promise的resolve函数里面"));
                }
                else{
                    reject(log("我在cook的promise的reject函数里面"));
                    a=2;
                }
                
            });
            return c;
        }


        function eat(){
            log("进入eat函数里面");
            var e=new Promise(function(resolve,reject){
                log("我在eat的promise里面");
                if(a==2){
                    resolve(log("在eat的promise的resolve函数里面"));
                }
                else{
                    reject(log("我在eat的promise的reject函数里面"));
                    a=3;
                }
            })
            return e;
        }

        function wash(){
            log("进入wash函数里面");
            var w=new Promise(function(resolve,reject){
                log("我在wash的promise里面");
                if(a==3){
                    resolve(log("在wash的promise的resolve函数里面"));
                }
                else{
                    reject(log("我在wash的promise的reject函数里面"));
                    a=4;
                }
            })
            return w;
        }


        // cook().then(eat).then(wash);
        cook().then(eat).then(wash).catch(function(data){
            log(data)
        });

在cook、eat、wash函数 定义了promise要返回,不然在链式调用的时候回报错Cannot read property 'then' of undefined

以上代码的结果,可以看出,进入cook函数后,判断a=1,然后执行了resolve方法。当进入了eat函数后,a!=2,那么执行reject方法,执行了reject方法后,我们不会再进行往下的链式调用。

将代码的判断条件改一下

        var a=1;
        function log(s){
            console.log(s);
        }

        function cook(){
            log("进入cook函数");
            var c=new Promise(function(resolve,reject){
                if(a==1){
                    resolve(log("在cook的promise的resolve函数里面"));
                    a=2;
                }
                else{
                    reject(log("我在cook的promise的reject函数里面"));
                    
                }
                
            });
            return c;
        }


        function eat(){
            log("进入eat函数里面");
            var e=new Promise(function(resolve,reject){
                log("我在eat的promise里面");
                if(a==2){
                    resolve(log("在eat的promise的resolve函数里面"));
                    a=3;
                }
                else{
                    reject(log("我在eat的promise的reject函数里面"));
                    
                }
            })
            return e;
        }

        function wash(){
            log("进入wash函数里面");
            var w=new Promise(function(resolve,reject){
                log("我在wash的promise里面");
                if(a==3){
                    resolve(log("在wash的promise的resolve函数里面"));
                    a=4;
                }
                else{
                    reject(log("我在wash的promise的reject函数里面"));
                    
                }
            })
            return w;
        }


        // cook().then(eat).then(wash);
        cook().then(eat).then(wash).catch(function(data){
            log(data)
        });

可以看出,如果满足条件,那个就会一直往下执行。

all()方法

promise有个all方法,可以执行所有传入的方法后再调用最后的方法。

我们改一下代码的链式调用一块以及cook的代码 cook函数的resolve方法中不给a赋值

          Promise.all([cook(),eat(),wash()]).then(function(data){
            log("全部代码都执行完")
        }).catch(function(){
            log("有代码出错啦")
        })

可以看出cook、eat、wash方法都执行一遍报错了,在链式那里catch到,并报告出错

race()方法

这个方法跟all很相似,不过all是会执行所有的方法才会then回调,race方法是只要有一个异步操作执行完毕,就立刻执行 then 回调。注意:其它没有执行完毕的异步操作仍然会继续执行,而不是停止。我们给eat方法加了定时器

        function eat(){
            log("进入eat函数里面");
            var e=new Promise(function(resolve,reject){
                log("我在eat的promise里面");
                if(a==2){
                    
                    setTimeout(function(){
                        resolve(log("在eat的promise的resolve函数里面2"))
                    },1000);
                    
                }
                else{
                    reject(log("我在eat的promise的reject函数里面1"));
                    
                }
            })
            return e;
        }


        Promise.race([cook(),eat(),wash()]).then(function(){
            log("有方法执行完")
        }).catch(function(){
            log("有方法出错啦")
        })

知道这些方法后,我们开始做之前说的对比两个数据。

        var a="";
        var b="";
        function ajax1(){
            console.log("enter ajax1");
            var promise1=new Promise(function(resolve,reject){
                console.log("enter promise1");
                $.ajax({
                    type:"get",
                    url:"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd="+"a",
                    dataType:"jsonp",
                    jsonp:"cb",
                    success:function(data){
                    //   console.log(data.s[0])
                        a=data.s[0];
                        resolve(a);
                    },
                    error:function(error){
                        reject("ajax1 error")
                    }
                });
            });
            return promise1;
            
        }
        function ajax2(){
            console.log("enter ajax2");
            var promise2=new Promise(function(resolve,reject){
                console.log("enter promise2");
                $.ajax({
                    type:"get",
                    url:"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd="+"a",
                    dataType:"jsonp",
                    jsonp:"cb",
                    success:function(data){
                    //   console.log(data.s[0])
                        b=data.s[0];
                        resolve(b);
                    },
                    error:function(error){
                        reject("ajax2 error")
                    }
                })
            });
            return promise2;
        }
        function compare(){
            if(a!=b){
                console.log("different")
            }
            else{
                console.log("same")
            }
        }
        ajax1().then(ajax2).then(compare).then(function(data){
            console.log(data)
        });

在上述代码有有两个ajax方法来去百度引擎的数据,取回来后将数据进行对比,在链式调用中,先取ajax1数据后,进行取ajax2数据,之后再进行对比,得出结果。

代码我都放在github上,有兴趣的小伙伴可以看看

https://github.com/LittleBeautyMX/javascript-demo

有什么不对的地方,欢迎留言批评改正

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值