zoukankan      html  css  js  c++  java
  • 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('连接失败!');
                        }
                    })
                }
            }
    

      

  • 相关阅读:
    jsp 特殊标签
    poj 1753 Flip Game 高斯消元 异或方程组 求最值
    zoj 3155 Street Lamp 高斯消元 异或方程组 求方案数
    poj1222 EXTENDED LIGHTS OUT 高斯消元解异或方程组 模板
    zoj 3930 Dice Notation 模拟
    zoj 3157 Weapon 线段树求逆序对数
    hdu 1242 Rescue BFS+优先队列
    hdu 3466 Proud Merchants 贪心+01背包
    zoj 3689 Digging 贪心+01背包
    hdu 2602 Bone Collector 01背包模板
  • 原文地址:https://www.cnblogs.com/jelina/p/11154853.html
Copyright © 2011-2022 走看看