首页 > 代码库 > Promise笔记

Promise笔记

首先,让我们认识以下什么是Promise: 所谓Promise,就是一个对象,用来传递异步操作的消息,它代表了某个未来才会知道结果的事件。

听起来有些不知所谓,那么首先,console一下吧~

console.dir(Promise)

技术分享

可以看出它是一个构造函数,拥有accept、all等属性,prototype中有catch、chain、then等方法,这意味着其实例也将拥有这些方法~

 

接下来创建一个试试

var p = new Promise(function(resolve, reject){
    //异步操作
    setTimeout(function(){
        console.log(‘完成‘);
        resolve(‘回调结果‘);
    }, 2000);
});

解析:

Promise构造函数接受一个函数作为参数,该函数有两个参数resolve和reject

Promise对象有3种状态: Pending(进行中)、Resolved(已完成,又叫Fulfilled)、Rejected(已失败),

如果异步操作成功,则用 resolve 方法将 Promise 对象的状态,从 pending 变为 resolved;

如果异步操作失败,则用 reject 方法将 Promise 对象的状态,即从 pending 变为 rejected。

 

运行结果:两秒后输出 “完成”

由此发现一个问题:我们只是创建了一个实例,并未调用它!因此Promise实例创建时就运行了!因此一般做法是将其包在一个函数当中,需要时进行调用

function runasync(){
        var p = new Promise(function(resolve, reject){
            //异步操作
            setTimeout(function(){
                console.log(‘完成‘);
                resolve(‘回调结果‘);
            }, 2000);
        });  
        return p;
    };

//调用

runasync();

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

接下来是相关方法的使用:

then()

then接受一个函数或两个函数作为参数,第一个函数有data参数,data就是resolve传入的参数,第二个有err参数,err是reject传入的参数

eg: runasync().then(function(data){console.log(data)}); //输出完成  回调结果

于是乎我们将异步操作的结果传递过来,回调函数可在函数外部链式执行!

当然,如果只有一步异步操作,体现不出Promise的精华,但若有多个异步操作,Promise将省去大量代码!

eg:

function runasync(){
        var p = new Promise(function(resolve, reject){
            //异步操作
            setTimeout(function(){
                console.log(‘完成‘);
                resolve(‘回调结果‘);
            }, 2000);
        });  
        return p;
    };
    function runasync1(){
        var p = new Promise(function(resolve, reject){
            //异步操作
            setTimeout(function(){
                console.log(‘完成‘);
                resolve(‘回调结果1‘);
            }, 2000);
        });  
        return p;
    };
    function runasync2(){
        var p = new Promise(function(resolve, reject){
            //异步操作
            setTimeout(function(){
                console.log(‘完成‘);
                resolve(‘回调结果2‘);
            }, 2000);
        });  
        return p;
    };
    
    runasync().then(function(data){
        console.log(data);
        return runasync1();
    })
    .then(function(data){
        console.log(data);
        return runasync2();
    });

输出:

完成
回调结果
完成
回调结果1
完成

 

catch()

catch与then的第二个参数一样,专门用来指定reject情况下的操作,但它有一种特殊用法:

如果resolve的回调(也就是then)出现异常,在其后面接上catch,就不会卡死js,而是会进入catch方法中。

eg:

function runasync(){
        var p = new Promise(function(resolve, reject){
            //异步操作
            setTimeout(function(){
                console.log(‘失败‘);
                resolve("11");
            }, 2000);
        });  
        return p;
    };
    
    runasync().then(function(data){
     //d未定义,一般情况下会报错,但接上catch不会 console.log(d); }).
catch(function(err){ console.log(err); })

输出:

失败
ReferenceError: d is not defined(…)

 

all()

如果有多个异步操作同时执行,而我们想在它们都执行完成后再进行操作应该怎么办?Promise提供了all()方法

Promise.all(array)

array是Promise实例对象数组

eg:

function runasync(){
        var p = new Promise(function(resolve, reject){
            //异步操作
            setTimeout(function(){
                console.log(‘完成‘);
                resolve(‘回调结果‘);
            }, 2000);
        });  
        return p;
    };
    function runasync1(){
        var p = new Promise(function(resolve, reject){
            //异步操作
            setTimeout(function(){
                console.log(‘完成‘);
                resolve(‘回调结果1‘);
            }, 2000);
        });  
        return p;
    };
    function runasync2(){
        var p = new Promise(function(resolve, reject){
            //异步操作
            setTimeout(function(){
                console.log(‘完成‘);
                resolve(‘回调结果2‘);
            }, 2000);
        });  
        return p;
    };
    
    Promise.all([runasync(), runasync1(), runasync2()]).then(function(datas){
        console.log(datas);
    }, function(errs){
        console.log(errs);
    })

输出:

完成
完成
完成
["回调结果", "回调结果1", "回调结果2"] //可见将结果以数组的形式返回
 
如果其中一个是reject呢?
    function runasync(){
        var p = new Promise(function(resolve, reject){
            //异步操作
            setTimeout(function(){
                console.log(‘完成‘);
                resolve(‘回调结果‘);
            }, 2000);
        });  
        return p;
    };
    function runasync1(){
        var p = new Promise(function(resolve, reject){
            //异步操作
            setTimeout(function(){
                console.log(‘完成‘);
                resolve(‘回调结果1‘);
            }, 2000);
        });  
        return p;
    };
    function runasync2(){
        var p = new Promise(function(resolve, reject){
            //异步操作
            setTimeout(function(){
                console.log(‘完成‘);
                reject(‘回调结果2‘);
            }, 2000);
        });  
        return p;
    };
    
    Promise.all([runasync(), runasync1(), runasync2()]).then(function(data){
        console.log(data);
    }, function(err){
        console.log(err);
    })

输出:

完成
完成
完成
回调结果2

可见只要有一个异步结果是失败状态,整个函数的执行结果将被认为是失败的

 

race()

all方法是典型的 "谁跑得慢就以谁为准",而race(赛跑)便是"谁跑得快就以谁为准"

其返回的结果,是最快完成的异步操作返回的结果

    function runasync(){
        var p = new Promise(function(resolve, reject){
            //异步操作
            setTimeout(function(){
                console.log(‘完成‘);
                reject(‘回调结果‘);
            }, 5000);
        });  
        return p;
    };
    function runasync1(){
        var p = new Promise(function(resolve, reject){
            //异步操作
            setTimeout(function(){
                console.log(‘完成‘);
                resolve(‘回调结果1‘);
            }, 2000);
        });  
        return p;
    };
    function runasync2(){
        var p = new Promise(function(resolve, reject){
            //异步操作
            setTimeout(function(){
                console.log(‘完成‘);
                resolve(‘回调结果2‘);
            }, 3000);
        });  
        return p;
    };
    
    Promise.race([runasync(), runasync1(), runasync2()]).then(function(data){
        console.log(data);
    }, function(err){
        console.log(err);
    })

输出:

完成
回调结果1
完成
完成

//其返回的结果与成功/失败无关,只求最快

 

 

Promise笔记