谈谈ES6中Promise的使用

Promise是一个对象,同时也是一个构造函数,为了对Promise有一个直观的认识,首先咱们把Promise直接在控制台打印出来:
Promise
经过这张图片咱们能够很清除地看到,Promise本身身上有all,race,resolve,reject这些咱们熟悉的方法,而在原型之上,则有then,catch,finally这些一样很熟悉的方法。javascript

Promise怎么用?

既然Promise是一个构造函数,那咱们就new一个实例出来吧:java

var p = new Promise(function(resolve,reject){
    setTimeout(() =>{
        if(1){    //假设操做成功
            console.log("执行成功")
            resolve("执行成功以后的数据")
        }else{
            console.log("执行失败")
            reject("执行失败以后的数据")
        }
    }, 1000)
})

Promise接收一个参数,是一个函数,该函数有两个参数:resolve和reject,也是两个函数,这两个函数是javascript引擎给咱们提供的,不用咱们本身去部署。
Promise有三种状态:pending/fulfilled/rejected 。pending就是未决,fulfilled能够理解为成功,rejected能够理解为失败。数组

resolve函数的做用是将Promise的状态置为fullfiled,当状态变成fullfiled时,then方法的第一个回调会执行,reject函数是将Promise的状态置为rejected,当状态变成rejected时,then方法的第二个回调或者catch方法里的回调会执行异步

而且Promise有如下特色:
1 .对象的状态不受外界影响,只有内部异步操做的结果能够修改他的状态,任何其余操做都没法修改他的状态。
2 .一旦状态发生改变,就不会再变,任什么时候候均可以获得这个结果。若是改变已经发生了,只要添加回调函数,任什么时候候均可以获得返回值。函数

运行以上代码,咱们在控制台能够看到打印出了执行成功:
运行结果
注意,这里咱们只是new了一个Promise对象,并无去调用它,里面代码就已经执行了,因此咱们通常都是把Promise放到一个函数里面,在须要的时候调用,为了方便探讨,咱们对函数作以下封装:spa

function createPro(num,time){
    return new Promise(function(resolve,reject){
        setTimeout(() =>{
            if(num > 5){
                console.log("执行成功")
                resolve("执行成功以后的数据")
            }else{
                console.log("执行失败")
                reject("执行失败以后的数据")
            }
        }, time)
    })
}

咱们封装了一个函数,返回一个Promise对象,咱们给该函数传递两个参数,num和time,num用来控制异步操做的结果,num大于5理解为执行成功,time用来控制延迟时间。
刚才咱们看到函数已经执行成功,可是resolve和reject传递的参数去哪里了?还记得刚才咱们说过当Promise状态改变时会执行then或者catch方法里的回调吧,没错,在回调函数里面就能够取到传递的数据。code

then方法和catch方法

then中有2个参数,第一个参数是状态变为成功后应该执行的回调函数,第二个参数是状态变为失败后应该执行的回调函数。对象

createPro(10,1000).then((data)=>{
    console.log("num为10时then方法的第一个参数收到的:"+data)
},(err)=>{
    console.log("num为10时then方法的第二个参数收到的:"+err)
})
createPro(1,1000).then((data)=>{
    console.log("num为1时then方法的第一个参数收到的:"+data)
},(err)=>{
    console.log("num为1时then方法的第二个参数收到的:"+err)
})

执行以上函数,咱们观察控制台的打印状况:
执行结果blog

因为第一次调用createPro时,咱们给num传的值为10,比5要大,因此在函数内部执行了resolve方法,Promise的状态变成了fullfiled,then方法的第一个回调被执行,而且接收到了resolve方法传递来的数据,而在第二次调用createPro时,咱们给num传的值为1,比5要小,因此在函数内部调用了reject方法,Promise的状态变成了rejected,then方法的第二个回调被执行,而且收到了reject传递的数据。
固然then方法也能够只接收一个回调,即异步操做成功时执行的回调。
catch方法是用来接收异步操做失败的结果,效果和then方法的第二个参数同样:接口

createPro(1,1000).then((data)=>{
    console.log("then方法的第一个参数收到的:",data)
}).catch((err)=>{
    console.log("catch方法里收到的:",err)
})

咱们在控制台能够看到打印了:
执行结果

若是咱们想要无论成功仍是失败,都要执行一些操做能够用Promise.finally(),可是该方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态究竟是fulfilled仍是rejected。这代表,finally方法里面的操做,是与状态无关的,不依赖于 Promise 的执行结果。

Promise的链式操做

Promise的then方法以后会继续返回一个Promise对象,能够继续调用then方法,而接收的参数值就是上一个then方法return的结果:

createPro(10,1000).then((data)=>{
    console.log("then方法的第一个参数收到的:"+data)
    return 100
}).then(data=>{
    console.log("第二个then方法接收到的的参数",data)
})

执行结果
咱们能够看到在第二个then中接收到了咱们在第一个then方法中返回的数字100.固然咱们也能够返回一个Promise对象

createPro(10,1000).then((data)=>{
    console.log("第一个then:",data)
    return createPro(10,1000)
}).then(data=>{
    console.log("第二个then:",data)
    return createPro(2,1000)
}).then(data=>{
    console.log("第三个then:",data)
    return createPro(10,1000)
}).catch(err=>{
    console.log("公共的catch方法:",err)
})

运行结果以下:
执行结果

咱们能够看到函数依次执行,因此Promise能够解决所谓“地狱回调”的问题,而且若是中途有异步操做执行失败,都会执行catch里面的回调。

Promise.all和Promise.race

Promise的all方法提供了并行执行异步操做的能力,而且在全部异步操做执行完后才执行回调。Promise.all接收一个数组参数,里面的异步操做的并行执行的,等到它们都执行完后才会进到then里面。那么,异步操做返回的数据哪里去了呢?都在then里面呢,all会把全部异步操做的结果放进一个数组中传给then。
咱们对createPro函数设置不一样的延迟时间:

Promise.all([createPro(10,1000),createPro(10,2000),createPro(10,3000)]).then(data=>{
    console.log(data)
})

执行以上代码,咱们能够看到控制台每隔一秒打印出了一次“执行成功”,而且在最后打印出了传递的数据,是一个数组:
执行结果
Promise.all有一个常常用到的场景就是,在一个页面有多个请求接口,当全部接口都请求到数据以后,关闭loading遮罩层,这时候咱们就能够用到Promise.all方法。

理解了Promise.all再来看Promise.race就好理解多了,all方法的效果其实是「谁跑的慢,以谁为准执行回调」,那么相对的就有另外一个方法「谁跑的快,以谁为准执行回调」,这就是Promise.race:

Promise.race([createPro(10,1000),createPro(10,2000),createPro(10,3000)]).then(data=>{
    console.log(data)
})

运行结果以下:
执行结果
咱们在控制台能够看到,一秒以后打印出了“执行成功”,而且拿到了resolve传递的数据,可是另外两个函数并无中止运行,因此咱们看到每间隔一秒又打印出了“执行成功”。

关于Promise经常使用的方法先写这些了,另外还有Promise.resolve和Promise.reject等方法有时间再研究,因为做者水平有限,文章不免有错误之处,还请大神斧正。

相关文章
相关标签/搜索