zoukankan      html  css  js  c++  java
  • es6 Promise

    https://www.jianshu.com/p/c98eb98bd00c

    相信凡是写过javascript的童鞋也一定都写过回调方法(callback),简单说回调方法就是将一个方法func2作为参数传入另一个方法func1中,当func1执行到某一步或者满足某种条件的时候才执行传入的参数func2,例如下面的代码段

    // 当参数a大于10且参数func2是一个方法时 执行func2
    function func1(a, func2) {
        if (a > 10 && typeof func2 == 'function') {
            func2()
        }
    }
    
    func1(11, function() {
        console.log('this is a callback')
    })
    

    一般来说我们会碰到的回调嵌套都不会很多,一般就一到两级,但是某些情况下,回调嵌套很多时,代码就会非常繁琐,会给我们的编程带来很多的麻烦,这种情况俗称——回调地狱。极端情况如下图:

     
    badcallback.jpeg

    由此,Promise的概念就由社区提出并实现,作用与回调方法几乎一致,都是在某种情况下执行预先设定好的方法,但是使用它却能够让代码变得更简洁清晰

    什么是Promise

    Promise是异步编程的一种解决方案,它有三种状态,分别是pending-进行中resolved-已完成rejected-已失败

    当Promise的状态又pending转变为resolved或rejected时,会执行相应的方法,并且状态一旦改变,就无法再次改变状态,这也是它名字promise-承诺的由来

    ES6之前的Promise

    在ES6中,Promise终于成为了原生对象,可以直接使用。但是在这之前,小伙伴们想要使用Promise,一般会借助于第三方库,或者当你知道其中的原理以后,也可以手动实现一个简易的Promise

    当然,为了防止不可预知的bug,在生产项目中最好还是不要使用原生的或者自己编写的Promise(目前为止并不是所有浏览器都能很好的兼容ES6),而是使用已经较为成熟的有大量小伙伴使用的第三方Promise库,下面就为小伙伴推荐一个—— Bluebird

    Promise的基本用法

    声明一个Promise对象

    // 方法1
    let promise = new Promise ( (resolve, reject) => {
        if ( success ) {
            resolve(a) // pending ——> resolved 参数将传递给对应的回调方法
        } else {
            reject(err) // pending ——> rejectd
        }
    } )
    
    // 方法2
    function promise () {
        return new Promise ( function (resolve, reject) {
            if ( success ) {
                resolve(a)
            } else {
                reject(err)
            }
        } )
    }
    

    注意:实例化的Promise对象会立即执行

    Promise.prototype.then() VS Promise.prototype.catch()

    .then()方法使Promise原型链上的方法,它包含两个参数方法,分别是已成功resolved的回调和已失败rejected的回调

    promise.then(
        () => { console.log('this is success callback') },
        () => { console.log('this is fail callback') }
    )
    

    .catch()的作用是捕获Promise的错误,与then()的rejected回调作用几乎一致。但是由于Promise的抛错具有冒泡性质,能够不断传递,这样就能够在下一个catch()中统一处理这些错误。同时catch()也能够捕获then()中抛出的错误,所以建议不要使用then()的rejected回调,而是统一使用catch()来处理错误

    promise.then(
        () => { console.log('this is success callback') }
    ).catch(
        (err) => { console.log(err) }
    )
    

    同样,catch()中也可以抛出错误,由于抛出的错误会在下一个catch中被捕获处理,因此可以再添加catch()

    使用rejects()方法改变状态和抛出错误 throw new Error() 的作用是相同的

    当状态已经改变为resolved后,即使抛出错误,也不会触发then()的错误回调或者catch()方法

    then() 和 catch() 都会返回一个新的Promise对象,可以链式调用

    promise.then(
        () => { console.log('this is success callback') }
    ).catch(
        (err) => { console.log(err) }
    ).then(
        ...
    ).catch(
        ...
    )
    

    Promise实例的异步方法和then()中返回promise有什么区别?

    // p1异步方法中返回p2
    let p1 = new Promise ( (resolve, reject) => {
        resolve(p2)
    } )
    let p2 = new Promise ( ... )
    
    // then()中返回promise
    let p3 = new Promise ( (resolve, reject) => {
        resolve()
    } )
    let p4 = new Promise ( ... )
    p3.then(
        () => return p4
    )
    

    p1异步方法中返回p2

    p1的状态取决于p2,如果p2为pending,p1将等待p2状态的改变,p2的状态一旦改变,p1将会立即执行自己对应的回调,即then()中的方法针对的依然是p1

    then()中返回promise

    由于then()本身就会返回一个新的promise,所以后一个then()针对的永远是一个新的promise,但是像上面代码中我们自己手动返回p4,那么我们就可以在返回的promise中再次通过 resolve() 和 reject() 来改变状态

    Promise的其他api

    Promise.resolve() / Promise.reject()

    用来包装一个现有对象,将其转变为Promise对象,但Promise.resolve()会根据参数情况返回不同的Promise:

    参数是Promise:原样返回
    参数带有then方法:转换为Promise后立即执行then方法
    参数不带then方法、不是对象或没有参数:返回resolved状态的Promise

    Promise.reject()会直接返回rejected状态的Promise

    Promise.all()

    参数为Promise对象数组,如果有不是Promise的对象,将会先通过上面的Promise.resolve()方法转换

    var promise = Promise.all( [p1, p2, p3] )
    promise.then(
        ...
    ).catch(
        ...
    )
    

    当p1、p2、p3的状态都变成resolved时,promise才会变成resolved,并调用then()的已完成回调,但只要有一个变成rejected状态,promise就会立刻变成rejected状态

    Promise.race()

    var promise = Promise.race( [p1, p2, p3] )
    promise.then(
        ...
    ).catch(
        ...
    )
    

    “竞速”方法,参数与Promise.all()相同,不同的是,参数中的p1、p2、p3只要有一个改变状态,promise就会立刻变成相同的状态并执行对于的回调

    Promise.done() / Promise. finally()

    Promise.done() 的用法类似 .then() ,可以提供resolved和rejected方法,也可以不提供任何参数,它的主要作用是在回调链的尾端捕捉前面没有被 .catch() 捕捉到的错误

    Promise. finally() 接受一个方法作为参数,这个方法不管promise最终的状态是怎样,都一定会被执行



    作者:君未来我已老
    链接:https://www.jianshu.com/p/c98eb98bd00c
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    PC版优酷的一次异常
    颜宁开讲啦谈理性思考
    李彦宏开讲啦谈判断能力
    尝试插入cctv视频
    selenium中quit与close方法的区别
    CodeForces 131C The World is a Theatre(组合数)
    CodeForces 446A DZY Loves Sequences(dp)
    UVA 1631 Locker(密码锁)(dp记忆化搜索)
    UVA 1630 Folding(串折叠)(dp记忆化搜索)
    UVA 1629 Cake slicing(切蛋糕)(dp记忆化搜索)
  • 原文地址:https://www.cnblogs.com/beimingbingpo/p/8549769.html
Copyright © 2011-2022 走看看