Promise,我是这么理解的!

一、promise不是承诺

Promise在英语里有希望、承诺之意,在Javascript,它是异步解决方案。有人质疑已经有了更高级异步解决方案async/await,还有必要了解promise?是的,因为大部分项目异步方案使用promise,除此之外,promise也是实现async/await的基础。最重要的,promise仍是前端面试热点。

Promise:统一异步操作方法控制器

二、大话promise

如果你看到标题便阅读本文,想必已经了解promise基础知识!

1、resolve不是完成

阮老师课程有句话,“为了行文方便,本章后面的resolved统一只指fulfilled状态”,说明resolved并不一定是代表完成。

//终于排到队了....
function bookDinner(msg) {
    return new Promise((resolve, reject) => {
            resolve(msg)
        }).then(msg => console.log("完成订单:", msg))
        .catch(msg => console.log("订单异常:", msg))
}复制代码

上例为举例排队订餐场景,排队过程中状态是pending。排到你后,收银台收银并给你一个号牌,需要等待取餐,这个时候状态便是resolved,收银台仅仅给了你一个订餐成功的承诺,人家比一定保证你能吃上。一旦发生异常或者其他事件,仍可能导致订单失败。

bookDinner(Promise.reject("厨师带着老板娘跑了!"))//'订单异常: 厨师带着老板娘跑了!'复制代码

resolved不能代表fullfilled

2、希望用不到的catch

上例中我们使用Promise构造函数创建promise实例,并赋予了实例不能改变的状态。在执行任务中我们使用到了catch方法,用于指定状态为rejected或发生错误的回调函数。

catch方法是then(null,rejection)或者then(undefined,rejection)的别名,那为什么会有catch方法?

  • 感官上更接近try/catch方法,代码易读;
  • 捕捉错误的能力,catch可以捕捉到前面promise对象(then方法也是promise对象)的错误;
let p = new Promise((resolve, reject) => {
    resolve()
})
//第一种:
p.then(() => { throw new Error('rejected') })
    .catch(v => console.log(v)) // "Error: rejected"
//第二种:
p.then(() => { throw new Error('rejected') }, v => console.log(v)) //报错复制代码
  • catch方法只能捕获其前的错误;
let p = new Promise((resolve, reject) => {
    resolve()
})
p.catch(err => console.log(err))
    .then(() => { throw new Error('catch后的报错') })//报错获取不到复制代码
  • catch方法报错可以在下一个catch方法获取,因为catchthen的变形。
let p = new Promise((resolve, reject) => {
    reject()
})
p.catch(() => { throw new Error('catch后的报错') })
    .catch(err => console.log(err)) //'Error: catch后的报错'复制代码

Promise 对象抛出的错误不会传递到外层代码,即不会影响其他任务正常执行,通俗的说法就是“Promise 会吃掉错误”。

console.log('start....')
let p = new Promise((resolve, reject) => {
    console.log('promise')
    throw new Error("是否会影响其他代码?")
})
p.then(v => console.log(v))
console.log('end!')
// start....
// promise
// end!
//报错:Uncaught (in promise) Error: 是否会影响其他代码?复制代码

3、高要求Promise.all

promise.all([]):数组内所有promise实例状态均为fullfilled,数组promise容器才为fullfilled。数组只要有一个状态rejected,数组promise容器状态九尾rejected。

这个方法确实挺有意思,还是以咱们点餐为例,食物和勺子都得具备才完成吃饭的任务,吃饭状态才能是fullfilled。任何一项不满足的话,对于吃饭任务来说,状态便是rejected

//获得食物
function getFood() {
    return Promise.resolve("盖饭")
}
//获得勺子
function getSpoon() {
    return Promise.resolve('勺子')
}
//吃饭
function eatFood() {
    return Promise.all([getFood(), getSpoon()])
}

eatFood().then(v => console.log('吃饭:',v))//'吃饭:["盖饭", "勺子"]'
    .catch(err => console.log(err)) 复制代码

如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()catch方法。

上边的例子我们稍加改变,服务员迟迟不给你拿勺子,这个时候,针对getSpoon这个任务报了个错,服务员立马知道了,拿来勺子,让你完成吃饭任务。其实是catch方法返回了一个新的实例。

//获得食物
function getFood() {
    return Promise.resolve("盖饭")
}
//获得勺子
function getSpoon() {
    return Promise.reject('还没给勺子')
}
let getSpoonAgin = getSpoon().then(v => v).catch(err => console.log(err))
//吃饭
function eatFood() {
    return Promise.all([getFood(), getSpoonAgin])
}

eatFood().then(v => console.log("吃饭:", v)) //'吃饭:["盖饭", undefined]'
    .catch(err => console.log("未能吃饭:", err))
}复制代码

4、竞争上岗Promise.race

promise.race:与promise.all类似,参数也是promise实例数组。哪个promise实例优先"到达",promise.race容器的状态就是先到达的promise实例状态。

继续点餐的例子,大家工作比较忙,中午只能等待15分钟,为了吃上饭你点了两份饭,毕竟胃容量有限,只能哪份先来就吃哪份(杠精们,不要抬杠哈!)当然此处只是举了两个任务状态都是fullfilled的例子。

function getFood1() {
    return Promise.resolve("盖饭")
}

function getFood2() {
    return Promise.resolve('饺子')
}

function eatFood() {
    return Promise.race([getFood1(), getFood2()])
}

eatFood().then(v => console.log("吃饭:", v)) //'吃饭: 盖饭'
    .catch(err => console.log("未能吃饭:", err))复制代码

三、写在最后

以上只是针对Promise运行方式以及部分方法进行说明,在项目实战中Promise的使用远比上边所说的例子复杂,希望本篇对于您理解promise异步解决方案有所帮助。

具体在使用中细节可以学习阮一峰老师ES6课程。

如果想要了解任务执行顺序的,可阅读聊聊前端面试之输出顺序

谢谢您的阅读,请多指教!


转载于:https://juejin.im/post/5c25bb756fb9a049dc025014

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值