浅谈Promise

特点

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

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

Promise是什么

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

浅谈Promise_第1张图片
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)// 此处接收的是方法三传递在状态
            //...
        }) 
        // ...

打印结果如下:


浅谈Promise_第2张图片
链式操作执行结果

如上面执行时的结构就是链式结构,当然这里我们在.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)// 所有的异步结果
            })

执行结果如下:


浅谈Promise_第3张图片
all方法执行结果

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

race方法

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

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

打印结果如下:


浅谈Promise_第4张图片
race方法执行结果

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

你可能感兴趣的:(浅谈Promise)