Promise 小结

SegmentFault

共 3138字,需浏览 7分钟

 · 2021-02-24

作者:runrunlolz
来源:SegmentFault 思否社区




Promise 的生命周期


每个Promise都有自己的一个生命周期,开始未处理然后变成已处理。开始pedding状态表示进行中,操作结束后。Promise可能进入以下两种状态某一个:


  • Fuiflled Promise操作完成。
  • Rejected 程序错误或者其他原因Promise为可以完成。


内部[[PromiseState]]用来表示三个状态:pending,fulfilled及rejected。这个属性并没有暴露在Promise对象上,所以检测不到。Promise状态改变的时候通过then获得。

所有Promise都有then方法,两个参数:第一个是Promise的状态变为fulfilled时候调用的函数,与异步操作有关数据传递给这个参数。第二个是变为rejected时执行的函数,失败相关附加数据可以通过参数传递给这个拒绝函数。

  • Tips

注意new Promise的时候传递函数会立即执行并且函数体内的操作是一个同步操作。

new Promise((res,rej) =>{}),接收一个函数作为参数,函数有两个参数是两个callback表示成功和失败的时候执行的。

    let p = new Promise((res,rej) => {
        console.log(1,'1')
        res("success")
        console.log(2,'2')
    })
    p.then((resolve)=>{
        console.log(resolve,'resolve')
    },(reject)=> {
        console.log(reject,'reject')
    })
    console.log(4)
    // 输出顺序 1 2 4 success




Promise 链的返回值


Promise链的一个重要特性就是可以给下游Promise传递数据,如果在完成处理程序中指定一个返回值,则可以沿着这条链继续传递数据。
  • Tips:
  • Promise链中的返回值如果是Promise对象的话根据返回的Promise状态进行执行对应then和catch,如果return一个非Promise那么会把它使用Promise.resolve包装成为一个fulfilled状态的Promise。
  • 如果then中没有return值,那就相当于return一个空的Promise对象(已完成状态)。比如:

let a = new Promise((res,rej) => {
    res(6)
})
a.then((res) => {
    console.log(res,'第一个执行完成')
    // 6
}).then(res=> {
    console.log("第二个返回打印",res)
    // 第二个返回打印 undefined
})

链式调用Promise:

let p1 = new Promise(function (resolve,reject) {
    resolve(42)
})

p1.then(function(value) {
    console.log(value)
    // return一个常量 then中的return会自动包装为Promise.resolve(xx)
    return value+1
}).then((res) => {
    console.log(res) // 43
})

// 拒绝处理程序中是同样的
let p1 = new Promise((reslove,reject) => {
    reject(42)
})

p1.catch((rej) => {
    console.log(rej)
    return rej+1 // return非Promise对象,使用Promise.resolve包装
}).then((value) => {
    console.log(value) //43
})




Promise 错误解决方案


Promise的错误捕捉有两种方式


  1. then函数的第二个参数。

let a = new Promise((res,rej) => {
    rej(2)
})

a.then( (res) => {
    // success do
},(rej) => {
    // reject do
    console.log(2) // 2
})

  1. catch函数

let a = new Promise((res,rej) => {
    rej(2)
})
a.then(res => {
    // success do
}).catch(err => {
    // do sth
})

catch函数可以在链式调用的时候当作整个链的Promise错误处理程序。

a.then(res=> {
    
}).then(res=> {
    
}).then((res) => {
    
}).catch(rej => {
    // 任意一个环节走到错误都会走到.catch这里
    // 并且无return中断环节的执行(因为已经catch失败,第一个then就调用不到了,所以链式结束)。
})



Promise 的继承


Promise类和其他内建类型一致,也可以作为基类派生类,所以也可以定义自己的Promise变量来扩展Promise的功能。


class MyPromise extends Promise {
    // 使用默认的Promise构造函数
    success(resolve,reject) {
        return this.then(reslove,reject)
    }
    failure(reject) {
        return this.catch(reject)
    }
}
let promise = new MyPromise(function (resolve,reject) {
    resolve(42)
})
promise.success(function(value) {
    console.log(value)
},function(value) {
    console.log(value)
})

// or
promise.failure(function (value) {
    console.log(value)
})

这个例子中扩展了两个success和failure方法。这两个方法都通过this调用它模仿的方法,派生Promise与内建Promise功能一致,只不过多了success和failure这两个可以调用的方法。

用于静态方法会也会被继承,因此派生的Promise也都存在MyPromise.resolve(),MyPromise.reject(),MyPromise.all(),MyPromise.race()静态方法。

后两者与内建方法完全不同,前两个稍有不同。




点击左下角阅读原文,到 SegmentFault 思否社区 和文章作者展开更多互动和交流,扫描下方”二维码“或在“公众号后台回复“ 入群 ”即可加入我们的技术交流群,收获更多的技术文章~

- END -


浏览 8
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报