• Promise的用法


    一、什么是Promise?

      Promise对象表示一个异步操作的最终状态(成功或失败),主要用于多层回调嵌套或处理多并发请求。

      接收两个参数:resolve表示成功,reject表示失败。

         new Promise(function(resolve,reject){...})
    

      来看一个例子

            new Promise(function(resolve,reject){
                resolve();
                reject();
            }).then(function(){
                console.log('成功!')
            },function(){
                console.log('失败!')
            })
    

      运行结果:成功!

      分析一下:如果resolve执行后,执行then里面的第一个函数;如果reject执行后,则执行then里面的第二个函数。

           Promise最终只表示一个状态,要么成功,要么失败,一个执行成功,另一个不看。此例中,resolve执行后,reject就不执行了。故只执行第一个函数。相反,如果reject先执行,那么resolve对应的函数就不执行了。

      换一种写法再来看下:

            new Promise(function(resolve,reject){
                resolve();
                reject();
            }).then(function(){
                console.log('成功!')
            }).catch(function(){
                console.log('失败!')
            })
    

      将reject对应的函数写在catch里面是不是更清晰了?

      那什么时候该执行resolve(),什么时候该执行reject()呢?先看一个小例子(后面会更详细讲用途)

      

         let flag = false;
            new Promise(function(resolve,reject){
                flag ? resolve() : reject();
            }).then(function(){
                console.log('成功!')
            }).catch(function(){
    console.log('失败!')
    })

      运行结果: 失败!

      就是当需要根据两种状态(成功或失败)分别写对应的逻辑处理的时候,分别执行resolve和reject。那可能会问,那我为什么不用 if……else直接写呢?

      因为Promise的强大还在于可以链式调用,并且可以将返回结果作为参数继续使用,类似多层回调。

      

      

            new Promise(function(resolve,reject){
                resolve([1,2]);
                reject();
            }).then(function(arr){
                let [arg1,arg2] = arr; //这里解构赋值
                var result1 = arg1+arg2; //1+2=3
                return result1;
            }).then(function(result1){
                var result2 = ++result1; //4
                return result2;
            }).then(function(result2){
                alert(result2 * 2);  //8
            }).catch(function(){
                console.log('error')
            })
    

      运行结果:8

      如果throw一个错误,会被catch捕捉,并且catch后也可以链式写then,如下:

      

            new Promise(function(resolve,reject){
                resolve([1,2]);
                reject();
            }).then(function(arr){
                let [arg1,arg2] = arr; //这里解构赋值
                var result1 = arg1+arg2;
                return result1;
            }).then(function(result1){
                var result2 = ++result1;
                return result2;
            }).then(function(result2){
                throw 'this is a bug';
            }).catch(function(v){
                console.log(v); //打印this is a bug
                return 'abc'
            }).then(function(m){
                console.log(m); //abc
            })
    

      运行结果:

    二、Promise的静态方法:

    1. Promise.resolve()

    2. Promise.reject()

    3. Promise.race():接收一个数组为参数,多个Promise,谁快执行谁,无论resolve还是reject。

    4. Promise.all():接收一个数组为参数,数组里有一个失败则失败。(用于处理多并发请求)

      例子分别如下:

            Promise.resolve('hello').then(function(m){
                console.log(m);
            })
    

      运行结果:hello

            Promise.reject('this is error').then(function(){
    
            }).catch(function(err){
                console.log(err);
            })
    

      运行结果:this is error

            Promise.race([new Promise(function(resolve,reject){
                setTimeout(resolve,500,'one')
            }),new Promise(function(resolve,reject){
                setTimeout(resolve,400,'two') //比第一个快
            })]).then(function(str){
                alert(str);  //two
            }).catch(function(){
    
            })
    

      运行结果:two,再增加一个reject看下

            Promise.race([new Promise(function(resolve,reject){
                setTimeout(resolve,500,'one')
            }),new Promise(function(resolve,reject){
                setTimeout(resolve,400,'two')
            }),new Promise(function(resolve,reject){
                setTimeout(reject,300,'bug') //最快
            })]).then(function(str){
                alert(str);
            }).catch(function(err){
                alert(err);  //bug
            })
    

      运行结果:bug

            Promise.all([Promise.resolve('abc'),1,2]).then(function(m){
                alert(m);  //abc,1,2
            }).catch(function(err){
                alert(err);
            })
    

      运行结果:abc,1,2      增加一个reject看下

            Promise.all([Promise.resolve('abc'),Promise.reject('bug'),1,2]).then(function(m){
                alert(m);
            }).catch(function(err){
                alert(err); //bug
            })
    

      运行结果:bug  有一个失败则失败

    三、Promise用途例子(帮助更好的理解Promise)

      1、控制显隐

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            #div1{
                100px;
                height: 100px;
                background: #f80;
            }
        </style>
    </head>
    <body>
        <input type="button" value="点击" id="btn">
        <div id="div1"></div>
        <script>
            var btn = document.getElementById('btn');
            var div1 = document.getElementById('div1');
            var changeNode = true;
            btn.onclick = function(){
                show();
            }
            function show(){
                changeNode = !changeNode;
                new Promise(function(resolve,reject){
                    changeNode ? resolve() : reject();
                }).then(function(){
                    div1.style.display = 'block';
                }).catch(function(){
                    div1.style.display = 'none';
                })
            }
        </script>
    </body>
    </html>
    

      2、选项卡切换

      普通方法实现

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            div{
                display: none;
                100px;
                height: 100px;
                border: 1px solid #000;
            }
            div.active{
                display: block;
                background: #f00;
            }
            input.active{
                background: #f00;
            }
        </style>
    </head>
    <body>
        <input type="button" value="点击1" class="active">
        <input type="button" value="点击2" >
        <input type="button" value="点击3" >
        <div class="active">11111</div>
        <div>22222</div>
        <div>33333</div>
        <script>
            var btns = document.getElementsByTagName('input');
            var aDiv = document.getElementsByTagName('div');
            for(let i=0;i<btns.length;i++){
                btns[i].onclick = function(){
                    for(var j=0;j<btns.length;j++){
                        btns[j].className='';
                        aDiv[j].className='';
                    }
                    this.className = 'active';
                    aDiv[i].className = 'active';
                }
            }
        </script>
    </body>
    </html>
    

      效果:

       使用Promise实现自动切换

        <script>
            var btns = document.getElementsByTagName('input');
            var aDiv = document.getElementsByTagName('div');
            var index = 0;
            setInterval(show,1000);
            function show(){
                index++;
                return new Promise(function(resolve,reject){
                    index == btns.length ? reject() : resolve();
                }).then(function(){
                    for(var j=0;j<btns.length;j++){
                        btns[j].className='';
                        aDiv[j].className='';
                    }
                    btns[index].className = 'active';
                    aDiv[index].className = 'active';
                }).catch(function(){
                    index = -1;
              show(); }) } </script>

      

      3、使用Promise写ajax

            window.onload = function(){
                //调用封装好的ajax
                ajax('a.php','get').then(function(res){
                    console.log(res);
                }).catch(function(err){
                    console.log(err);
                })
    
                function ajax(url,method){
                    return new Promise(function(resolve,reject){
                        var xhr = new XMLHttpRequest();
                        xhr.open(url,method,true);
                        xhr.send(null);
                        xhr.onload=function(){
                            if(xhr.status >= 200 && xhr.status<300 || xhr.status==304){
                                resolve(xhr.responseText);
                            }else{
                                reject(xhr.status);
                            }
                        }
                        xhr.onerror=function(){
                            reject('连接失败!');
                        }
                    })
                }
            }
    

      

  • 相关阅读:
    实现控件的拖拽
    自定义控件——安卓旋转动画
    MD5简单实例
    TextView来实现跑马灯的效果
    Intent的简单使用
    SharedPreferences的封装
    ViewPager+fragment的使用
    安卓定时器
    2020重新出发,MySql基础,MySql视图&索引&存储过程&触发器
    2020重新出发,MySql基础,MySql表数据操作
  • 原文地址:https://www.cnblogs.com/jelina/p/11154853.html
Copyright © 2020-2023  润新知