美文网首页
浅谈Promise

浅谈Promise

作者: 这一世思念 | 来源:发表于2019-03-13 11:59 被阅读0次

    特点

    1.对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成)和Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变;

    2.一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从Pending变为Resolved;从Pending变为Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对Promise对象田静回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的;

    Promise是什么

    对于一个对象,我们如果想要了解,可以直接将其打印出来,通过console.log(Promise)将其打印出来,结果如下

    image

    通过上面的方法,我们可以知道promise是一个构造函数,有属于自己私有的all,reject,resolve,rece等方法,也有供实例化对象调用的方法,比如:catch,then等;

    使用方法

            // Promise里面传入函数类型的参数,这个函数类型的参数接收两个参数resolve reject
            var tempP=new Promise(function(resolve,reject){
                // 异步操作
                setTimeout(function(){
                    console.log('icessun');  // 一秒之后打印出icessun
                    resolve('执行了'); // resolve是成功后的回调函数 里面的“执行了”是传入的参数
                },1000)
            });
            // 那么tempP是一个实例对象,可以使用then方法(Promise原型上面的方法)
            tempP.then(function(){
                console.log(arguments);  // 会打印出一个类数组 ['执行了']
                
            })
            tempP.then(function(arg){
                console.log(arg);  // 会打印出“执行了” arg接收了resolve里面的参数
            })
    

    注意上面的代码我们可以看到,在我们new出一个实例化对象时,并没有调用,但是却自己执行了,所以在实际使用时,我们可以在函数中实例化promise对象,然后将其return出来,这样就可以控制其执行的时间,通过return出来的实例化对象,也可以使用Promise原型上的方法;代码如下:

          function tempFunction(){
                var tempP=new Promise(function(resolve,reject){
                        setTimeout(function(){
                        reslove('----接受----');
                        },2000);
                    });
                return tempP; // 返回tempP实例,使其可以使用Promise原型上面的方法
            }
            tempFunction(); // 调用执行tempFunction函数 得到一个Promis对象
    
            // 也可以直接这样调用
            tempFunction().then(function(data){
            console.log(data); // '----接受----'
            });
    

    Promise的链式操作

    promise对于多重回调写法非常简单,其传递状态以及维护状态的方式使得回调函数可以及时被调用,结构代码如下:

            function method1(){// 方法1
                var p=new Promise(function(resolve,reject){
                    setTimeout(function(){
                        console.log('方法一执行完毕')
                        resolve('method1');
                        },2000);
                });
    
                return p; // 返回p实例对象
            }
            function method2(){// 方法二
                var p=new Promise(function(resolve,reject){
                    setTimeout(function(){
                        console.log('方法二执行完毕')
                        resolve('method2');
                        },2000);
                });
    
                return p; // 返回p实例对象
            }
            function method3(){// 方法三
                var p=new Promise(function(resolve,reject){
                    setTimeout(function(){
                        console.log('方法三执行完毕')
                        resolve('method3');
                        },2000);
                });
    
                return p; // 返回p实例对象
            }
            // ...
            // 执行方法
            method1()
            .then(function(data){
                console.log(data)// 此处接收的是方法一传递的状态
                return method2()// 在回调中执行方法二
            })
            .then(function(data){
                console.log(data)// 此处接收的是方法二传递的状态
                return method3()// 在回调中执行方法三
            })
            .then(function(data){
                console.log(data)// 此处接收的是方法三传递在状态
                //...
            }) 
            // ...
    

    打印结果如下:


    链式操作执行结果

    如上面执行时的结构就是链式结构,当然这里我们在.then()中return出的是数据,在其后通过.then()就可以接收到;

    Promise私有方法

    resolve和reject使用

    Promise构造函数接收一个函数作为参数,该函数有两个参数: resolve,reject;表示成功或者失败时执行的方法,如果成功就执行resolve,如果失败则执行reject;

            function method(){
                var p=new Promise(function(resolve,reject){
                    setTimeout(function(){
                        var tempValue = Math.random()
                        if(tempValue> 0.5) {
                            console.log('执行resolve')
                            resolve(tempValue)
                        }else {
                            console.log('执行reject')
                            reject('这个数我不要')
                        }
                        },2000);
                });
                return p; // 返回p实例对象
            }
            // 方法执行
            method()
            .then((data) => {
                console.log(data) // 成功的结果
            }, (rejected, data) => {
                console.log(rejected) // 失败的结果
                console.log(data)
            })
    

    从上面的代码可以看出,.then()接收两个参数,第一个是参数接收的resolve的结果,第二个参数接收的reject的结果;

    catch方法

    我们知道浏览器处理异常的方法try...catch(),有一场进入catch,不阻断后续程序的执行;那么Promise的catch方法也是这样的效果,用来指定接收reject的回调;如下

            method()
            .then((data) => {
                console.log(data) // 成功的结果
            })
            .catch((rejected, data) => {
                console.log(rejected) // 失败的结果
                console.log(data)
            })
    
    all方法

    构造函数的方法,只能构造函数使用,并行执行异步操作,并且等待所有的异步操作完成后,才执行后续的回调;

              function f1() {
                 var p = new Promise(function(resolve, reject) {
                    setTimeout(function() {
                        console.log('方法一执行了')
                        resolve(1)
                    }, 2000)
                 })
                 return p
             }
             function f2() {
                 var p = new Promise(function(resolve, reject) {
                    setTimeout(function() {
                        console.log('方法二执行了')
                        resolve(2)
                    }, 3000)
                 })
                 return p
             }
             function f3() {
                 var p = new Promise(function(resolve, reject) {
                    setTimeout(function() {
                        console.log('方法三执行了')
                        resolve(3)
                    }, 1000)
                 })
                 return p
             }
             Promise.all([f1(), f2(), f3()])
                .then(function(results) {
                    console.log(results)// 所有的异步结果
                })
    

    执行结果如下:


    all方法执行结果

    如上我们可以看出,all方法接收一个数组作为参数,数组中是所有的方法,而all执行完毕之后,.then
    接收的也是一个数据数据,里面是所有异步方法的结果;

    race方法

    与all方法不同,all方法是等所有的异步方法执行完毕之后,也就是说等最后一个异步返回结果,all才会执行.then()方法,并接收结果;race方法则是取最快执行完毕的异步方法的结果为标准来执行.then中的回调函数;代码如下:

                Promise.race([f1(), f2(), f3()])
                .then(function(results) {
                    console.log(results)// 只有一个异步方法返回的结果,所以此时results不是数组
                })
    

    打印结果如下:


    race方法执行结果

    以上就是我个人参考他人文档对Promise的总结;

    相关文章

      网友评论

          本文标题:浅谈Promise

          本文链接:https://www.haomeiwen.com/subject/fhuevftx.html