理解 ES6 标准 Promise

阅读 1520
收藏 106
2017-08-11
原文链接:www.jianshu.com

ES6即ES2015,2015年6月正式发布,Promise在其中被列为正式规范,那么Promise到底是干什么用的,用了很多次,我也不是很清楚,总感觉云里雾里的,反正不知道,就先打印一下到底是啥呗


log.png
log.png

只看到是一个函数对象,再来打印一下


dir.png
dir.png
看到其又很多方法,我接触最多的也就是reject,resolve,all方法也小有涉及,最主要的是看到prototype上挂载了多个别的让我们眼熟的方法,就catch和then方法,先来new两个玩一下,当然启用严格模式,代码如下:
"use strict"
const weather = new Promise((resolve) => {
    setTimeout(() => {
        console.log("Sunny with Clouds");
        resolve({ temp: 29, conditions:"Sunny with Clouds"})
    }, 100)
})
const tweets = new Promise((resolve) => {
    // resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数
    // resolve是将Promise的状态置为fullfiled,reject是将Promise的状态置为rejected
    setTimeout(() => {
        console.log("i like cake, BBQ is good too!");
        resolve(["i like cake", "BBQ is good too!"])
    }, 100)
})

all方法

Promise
    .all([weather,tweets])
    .then(responses => {
        const [weatherInfo,tweetInfo] = responses
        console.log(responses[0], responses[1])     
    })

或者

Promise
    .all([weather,tweets])
    .then(responses => {
        const [weatherInfo,tweetInfo] = responses
        console.log(weatherInfo,tweetInfo)  
    })

或者

Promise
    .all([weather,tweets])
    .then(responses => {
        const [weatherInfo,tweetInfo] = responses
        console.log(weatherInfo,tweetInfo)
     })

结果:


array.png
array.png

更无奈的方法,回调函数封装也能实现,如下:

function test(callback){
    setTimeout(function(){
        console.log('i like cake');
        callback('BBQ is good too!');
    }, 2000);
}
test(function(data){
    console.log(data);
});

结果:


test.png
test.png

综上,效果一样,感觉Promise没什么用,多个函数回调函数实现没差别,但是没忘,在链式调用时这该如何?就一个一个实现,然后给callback传进去?没必要,Promise的优势在于,只要then方法中返回的是一个Promise对象,就可以一直用then来进行回调操作。

Promise链式操作的用法
Promise从表面上看,它只是能够简化层层回调的写法,而实质上,Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多。所以使用Promise的正确场景是这样的:

const postsPromise = fetch("http://wesbos.com/wp-json/wp/v2/posts")
const streetCarsPromise = fetch("http://data.ratp.fr/api/datasets/1.0/search/?q=paris")

Promise
    .all([postsPromise,streetCarsPromise])
    .then(responses => {
        return Promise.all(
            responses.map(
                response => response.json()
            )
        )       
    })
    .then(responses => {
        const [postInfo, carsInfo] =responses
        console.log([postInfo, carsInfo])   
    })

结果是这样的

chain.png
chain.png
reject的用法
平常见的主要是这种
var p = new Promise(function(resolve, reject){

上面只说了resolve,reject的作用就是把Promise的状态置为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。在平常见到的语句中,前者就主要接受成功时的回调,后者是失败时的回调,如果失败调用时,会卡死整个的JS,停止运行。
还有一个程序员中常见的catch方法,感觉功能和Java里面的try/catch差不多,在报错的时候运行catch里面的,得到catch里的运行结果。
最后一个all方法,上面以用过,但是迷迷糊糊的,看完接下来的对理解应该会有所帮助。
Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。在多个回调函数中就能体现作用,如上面的一段代码:

Promise
    .all([postsPromise,streetCarsPromise])
    .then(responses => {
        return Promise.all(
            responses.map(
                response => response.json()
            )
        )       
    })
    .then(responses => {
        const [postInfo, carsInfo] =responses
        console.log([postInfo, carsInfo])   
    })

在执行postsPromise时,同时streetCarsPromise也会运行,互不干涉,到了自己定义的时间就开始运行,显示结果。

总结:以上就是我觉得的ES6中Promise用得到的,当然还有一些其他done、finally、success、fail的方法或者属性,可能能见到,但是用的不多,就不解释了。。。

评论
说说你的看法