promise面试题

关于Promise 的问题一览

  • 什么是 promise
  • 传统的回调式异步操作有什么缺点?(Promise是如何解决异步操作)
  • Promise中的异步模式有哪些?有什么区别?
  • 如果想 Promise.all()和Promise.race()传递空数组,运行结果会有什么不同?
  • 如何确保一个变量是可信任的 Promise(Promise.resolve方法传入不同值的处理有哪些)
  • Promise是如何捕获异常的?与传统的 try / catch 相比有什么优势?

1.什么是promise

下面的回答很像在背概念,但是很精辟

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的API ,各种异步操作都可以用同样的方法进行处理,让开发者不用关注于时序和底层的结果。Promise 的状态具有不受外界影响和不可逆两个特点。

2.传统的回调式异步操作有什么缺点?(Promise是如何解决异步操作)

  • 传统的回调有五大信任问题
    1)调用回调过早
    2)调用回调过晚(或没有被调用)
    3)调用回调次数过少或过多
    4)未能传递所需的环境和参数
    5)吞掉可能出现的错误和异常

  • Promise 的解决办法
    1) 调用回调过早
    对于Promise 来说,即使是立即完成的 Promise 也无法被同步观察到,也就是说一个Promise调用 then() 的时候,即使这个 Promise 已经决议了,提供给 then的回调也总会被异步调用。

    2)调用回调过晚(或没有被调用)
    对于一个 Promise 对象注册每一个观察回调都是相对独立、互不干预的。而 Promise 对象调用 resolve() 和 reject() 时,每个注册的观察回调也都会被自动调用。所以这些观察回调的任意一个都无法影响或延误对其他回调的调用。
    此外,关于回调未调用,正常情况下,没有任何东西可以阻止 Promise 向你通知它的决议,即使你的 js代码报错了,一定会通过异常回调来获取到。如果Promise 永远不被决议的话, Promise 本身已提供了竞态的抽象机制来作为解决方案

    3)调用回调次数过少或过多
    promise 的定义方式使得它只能被决议一次。即使代码中出现多次决议,这个 Promise 也会接受第一次决议,并会忽略掉其他任何后续调用。所以任何通过 then() 注册的回调只会被调用一次

    4)未能传递所需的环境和参数
    凡是被决议的值,都会被传递到观察回调中,如果没有显示的决议也会传递一个 undefined 给观察回调。需要主要的是,Promise 只允许传一个决意值,其他值会被默默忽略掉

    5)吞掉可能出现的错误和异常
    如果在创建 Promise 时,存在 JS 代码错误,会直接导致该 Promise 的拒绝决议,那么你可以通过 reject() 来获取异常,代码中的任何异常都不会吞掉。

以上的回答十分的啰嗦,但是如果上面的五点都能记住的话,会了解很多关于 Promise 的细节问题,也会应对一些面试官的追问,如 Promise的 then()会不会被重复调用等。

3.Promise 中的异步模式有哪些?有什么区别?

这个问题会把面试者问懵。。。可以考虑另一种问法,或者直接进入下一个问题。
说一说 Promise.all( ) 和 Promise.race( ) 的区别。因为 ES6中的 Promise中只有这两个模式 all 和 race,其他的如 first、any、last等都是其他 Promise库提供的。

  • Promise.all( ) 和 Promise.race( ) 的区别
  1. all会将传入的数组中的所有 Promise 全部决议以后,将决议值以数组的形式传入到观察回调中,任何一个 Promise决议为拒绝,那么就会调用拒绝回调

  2. race会将传入的数组中的所有 promise 中第一个决议的决议值传递给观察回调,即使决议结果是拒绝的。

4.如果向Promise.all( ) 和 Promise.race( )传递空数组,运行结果会有什么不同?

all会立即决议,决议结果是 fullfilled, 值是 undefined
race会永远都不决议,程序卡死。。。

5.如何确保一个变量是可信任的Promise(Promise.resolve方法传入不同值的不同处理有哪些)

可以通过 Promise.resolve( )方法对不确定的值进行 Promise化,返回一个Promise对象。

如果是一个立即值,比如一个普通变量,那么该Promise会立即决议为成功
如果是一个Promise值,那么会将该Promise直接返回赋值给这个Promise,不会有额外开销
如果是一个类Promise值,比如其中含有名称为 then的成员变量,那么会将 then展开形成一个新的 Promise对象。

6.Promise是如何捕获异常的?与传统的 try / catch 相比有什么优势?

传统的 try / catch 捕获异常方式是无法捕获异步的异常的,代码如下

try{
    setTimeout(function(){
        undefined();   // undefined 不是一个方法,会抛出异常
    }500)
} catch(err){
    console.log(err)
}

而对于Promise对象来说,构造Promise实例时的代码如果出错,则会被认为是一个拒绝的决议,并会向观察回调中传递异常信息。所以即使是一个异步的请求,Promise也是可以捕获异常的,此外,Promise还可以通过 catch回调来捕获回调中的异常。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值