当前位置:首页 > 简单说说Promise

简单说说Promise

发布于 2018-04-17 阅读 317 次 Javascript ES6

js里面存在很多异步操作,大多时候我们需要等待异步操作完成之后再做一些事情,一般来说,最容易想到是回调函数,这个是我们常用的方式。但是如果我们回调里面又是一个回调呢,然后又一层回调,这样我们得代码就会变成倒金字塔形式,既不好看,又不易读,幸好ES6出现了Promise,使用promise我们可以像jquery那样链式调用。

先看一个简单的例子

new Promise(
    function(){
        var a = 10;
        setTimeout(function(){
            if(a>10){
                console.log(1);
            }else{
                console.log(2);
            }
        },3000);
    }
)

把这个输入到console里面我们发现直接会输出结果,当然我们不希望他直接执行,所以我们可以把这个放在一个函数中:

function Demo(){
    return new Promise(
        function(){
            var a = 10;
            setTimeout(function(){
                if(a>10){
                    console.log(1);
                }else{
                    console.log(2);
                }
            },3000);
        }
    )
}
Demo();

resolve 和 reject

Promise对象接收一个函数作为参数,这个函数有两个参数,resolve和reject,我们姑且认为resolve表示成功,reject表示失败,当然这个比喻并不是恰当的。
resolve是将Promise的状态置为fullfiled,reject是将Promise的状态置为rejected。

function Demo(){
    return new Promise(
        function(resolve, reject){
            var a = 10;
            setTimeout(function(){
                if(a>10){
                    console.log(1);
                    resolve('>10');
                }else{
                    console.log(2);
                    reject('<10');
                }
            },3000);
        }
    )
}

Promise.prototype.then

then方法返回的是一个新的Promise实例

var p = Demo().then(function(data){
    console.log(data);
    return Demo2();
})
console.log(p instanceof Promise)
//true

then方法接收1或者2个函数作为参数,当值传递一个参数时,这个函数只有Promise是fullfield状态的时候会进入这个函数,是rejected状态的时候会报错,所以一般我们传递两个参数比较好,传递两个参数第一个是fullfilled状态进入,第二个是rejected状态进入。

Demo().then(function(data){
    console.log(data);
},function(data){
    console.log(data);
});
//输出
//2
//<10

Promise链式调用

虽然then方法会返回一个Promise对象,但是这个对象是一个新的Promise对象不再是原来那个Promise对象,不一定符合我们的需求,所以我们可以在then的参数函数里面return我们希望的Promise对象。

Demo1().then(function(data){
    console.log(data);
    return Demo2();
})
    .then(function(data){
    console.log(data)
    return Demo3();
})
    .then(function(data){
    console.log(data)
});

function Demo1(){
    return new Promise(
        function(resolve, reject){
            var a = 20;
            setTimeout(function(){
                if(a>10){
                    console.log("Demo1执行完成");
                    resolve('Demo1 resolve>10');

                }else{
                    console.log(1);
                    reject("Demo1 reject<10");

                }
            },3000);
        }
    )
}
function Demo2(){
    return new Promise(
        function(resolve, reject){
            var a = 20;
            setTimeout(function(){
                if(a>10){
                    console.log("Demo2执行完成");
                    resolve('Demo2 resolve>10');

                }else{
                    console.log(2);
                    reject("Demo2 reject<10");

                }
            },3000);
        }
    )
}
function Demo3(){
    return new Promise(
        function(resolve, reject){
            var a = 20;
            setTimeout(function(){
                if(a>10){
                    console.log("Demo3执行完成");
                    resolve('Demo3 resolve>10');

                }else{
                    console.log(3);
                    reject("Demo3 reject<10");

                }
            },3000);
        }
    )
}
// 输出结果
// Demo1执行完成
// Demo1 resolve>10
// Demo2执行完成
// Demo2 resolve>10
// Demo3执行完成
// Demo3 resolve>10

Promise.all

接收一个数组,会执行完所有的异步操作之后,将结果放入results数组中
Promise.all将会返回一个新的Promise对象,该对象的状态由参数数组中的所有Promise对象状态决定,只要有一个是rejected则返回的Promise对象是rejected状态,所有Promise参数都为resolved则返回的Promise对象是resolved状态。

Promise.all([Demo1(),Demo2(),Demo3()])
.then(function(results){
    console.log(results);
})

如果promise.all里面的Promise对象有一个是rejected 的状态则进入不了then函数,这个时候我们需要用catch来捕获这个错误,否则就会报错。

Promise.all([Demo1(),Demo2(),Demo3()])
.then(function(results){
    console.log(results);
})
.catch(function(e){
    console.log(e);
})