js-Promise对象理解与使用

1.什么是Promise

Promise是异步编程的一种解决方案。相比于回调函数更加强大、更加合理。

Promise对象的两个特点:1.Promise对象状态不受外界影响 2.状态一旦改变就不会再变

Promise对象的三种状态:1.Pending (进行中) 2.Fulfilled (已成功) 3.Rejected (已失败)。Pending只会变为Fulfilled和Rejected中的其中一种,并且只要变为其中一种状态就会凝固,不会再发生改变,这时就成为Resolved (已定型)

缺点:1. 无法取消Promise 2.如果不设置回调,内部抛出的错误不会反映到外部

2. 基本用法
const isEven = (num) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (num & 1) { // 等价于对2求余
                reject(false)
            } else {
                resolve(true)
            }
        }, 2000);
    })
}

isEven(3).then(res => {
    console.log(res); 
}).catch(err => {
    console.log(err); // false
})

isEven() 返回 Promise 实例,由于传入的参数是3,所以2秒后执行 reject(false) 状态会由 Pending 变为 Rejected,之后可以通过原型上的方法then接收。因为是 reject 所以可以通过 catch 打印传来的值为 false

3. then()、catch()

这2个方法挂载在 Promise 的原型上

then:为Promise实例添加状态改变时的回调函数,then方法的第一个参数是成功的回调函数,第二个是失败的回调函数

catch:如果异步操作中抛出错误,状态则将变为Rejected,然后调用catch;在then中指定的回调函数如果运行时抛出错误,同样会被catch捕获。

4. Promise常用方法

Promise.all():将多个Promise实例包装为一个新实例

const p = Promise.all([p1, p2, p3])

// p 最后的状态由p1、p2、p3共同决定
// 1. 只有p1、p2、p3都变为成功、p最后的状态才是成功的,并返回对应的数组
// 2. 只要有一个是失败的,p就是失败的,并返回第一个失败的返回值

Promise.race():将多个Promise实例包装为一个新实例

const p = Promise.race([p1, p2, p3])

// p 最后的状态由p1、p2、p3哪个实例先改变状态决定
// 一旦其中一个实例改变了状态,那个改变状态的实例返回值传递给p的回调函数

Promise.resolve():将现有对象转为Promise对象

// 1.如果参数是Promise实例,则不作任何修改,直接返回

// 2.参数是thenable对象,如下obj就是thenable对象。resovle方法会将这个对象转为Promise对象,然后立即执行该对象的then方法。then方法执行后,对象p状态会变为resolved,从而立即执行p的then中的回调函数
const obj = {
    then: function (resolve, reject) {
        resolve('hi')
    }
}
const p = Promise.resolve(obj)
p.then((res) => {
    console.log(res);
})

// 3.不带有then方法的对象,或不是对象。返回的Promise实例状态从生成就是Resolved,所以回调函数会立即执行。
const p = Promise.resolve('hi')
p.then((res) => {
    console.log(res);
})

// 4.不带任何参数:直接返回一个Resolved的Promise对象

Promise.reject():返回一个新Promise实例,状态为Rejected

const p  = Promise.reject('wrong')

const p = new Promise((resolve, reject) => {
    reject('wrong')
})

p.then(null, (s) => {
    console.log(s)    
})
5. done()、finally()的实现

done方法的实现:

Promise.prototype.done = function (onFulfilled, onRejected) {
    this.then(onFulfilled, onRejected).catch(function (reason) {
        setTimeout((err) => {
            throw err
        }, 0);
    })
}

// done的使用
isEven(3).then().catch().done()

在Promise对象的回调链的最后无论是then还是catch,只要最后一个方法抛出错误,都有可能无法捕捉到(Promise内部的错误无法冒泡到全局)。done方法会捕获到任何可能出现的错误,并向全局抛出。

finnally()方法的实现:

Promise.prototype.finally = function (callback) {
    let p = this.constructor
    return this.then(value => {
        p.resolve(callback()).then(() => value)
    }, reason => {
        p.resolve(callback()).then(() => {throw reason})
    })
}

// finally的使用
isEven(3).then().catch().finally(() => {
    console.log('i will exec always');
})

finally方法用于指定不管Promise对象的状态如何都会执行的操作,与done方法最大的区别在于它接收一个普通的回调函数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值