前端必备:Promise知识扩展之thenable

在promise的学习中,你一定已经了解then()方法的基础,不了解的可以阅读:前端必备:从头开始,搞懂Promise

但是,除了基础用法,我们必须了解深层次的东西。

首先先来看第一点,也是面试可能会问到的问题。

Promise为什么能够实现异步?

答:Promise会完成控制权的转换。回调能够完成异步,但是什么时候触发回调由其它代码决定,而promise能够将控制权放在自己身上,然后再说js中异步的实现。

回调:使用回调函数来封装程序中的continuation,然后把回调交给第三方(甚至可能是外部代码),然后在合适的时机,这个第三方会调用这个continuation,来实现具体的功能。

控制权:我们通常使用回调来完成传统的异步实现,此时可以很明显的看出什么时候调用这个回调取决于第三方,即控制权在第三方,这样会出现很多问题:缺乏顺序性和可信任性。

所以,我们就需要将控制权从第三方反转回来,即不把continuation传给第三方,而是希望第三方给我们提供它的能力,然后由我们自己决定做什么,这种范式就是promise。

有点像吸星大法,你用我没有的能力帮我做事,但是你老是不按规矩来还不可靠,我生气了,把你的能力吸走,归为己有,然后我自己去做那些事。

接下来看第二点,也是本文的重点,thenable。

Thenable

在promise的使用中,判断某个值是不是真正的promise是很关键的。

你是否有疑问,我用promise构造函数,直接new一个promise,就算是查它的类型,我直接使用instanceof promise来判断不就好了么?这有什么好讲的?

答案是,没这么简单。

在我们常见的promise使用中,至少有3种方式可以创建promise。

  1. new promise(),这也是其它文章中说的标准promise。

  2. 使用非es6原生promise,也就是自己实现的promise时。

  3. 从其它浏览器窗口接到的promise,这个promise可能与当前窗口不同,所以那种检查方式无法识别promise实例。

所以说,上面说的那种检验方式,不行。

我们需要自己识别。

方法:then()作为promise的配套组件,我们只需要验证有没有then()就可以了,所以,我们提出了thenable的概念。

thenable:任何含有then()方法的对象或函数。

它的结构是不是很像promise,它们都有一个then()。

所以,我们无法找出promise时,就退而求其次,先找类似promise的,也就是thenable。

比如,我们在生活中养宠物,想养一只柴犬,有纯血统的、含有柴犬和其它品种狗狗的血统的、但血统检测很复杂,只能说它们都是柴犬,都在挑选范围内。

但就像无论是哪种血统,都得有柴犬的基本特征才行,检查这些特征,才能知道狗狗是不是柴犬,确定大的范围后,再想办法去确定血统。

同样的,js中也有检查类型,根据一个值的形态(所具有的属性),然后对它的类型做出假定,这种类型检查,一般用术语“鸭子类型”表示。

鸭子类型:如果看起来像鸭子,叫起来像鸭子,那它就是鸭子。

将这个类型检查应用在检查一个值是否为thenable()上也是可以的。

举个例子。

  if(p!==null&&(typeof p==="object"||typeof p==="function")&&(typeof p.then==="function")){
     console.log("这是一个thenable")
   }else{
     console.log("这不是一个thenable")
   }

这里我们先判断p是否是函数或对象,并且是否有then()方法,满足这些条件,我们将它认定为thenable。

注意:这样做能成功,但是有很大的缺点,如果把一个then()方法加入了函数或对象的原型链中,那么判断当前这个对象有没有then()就是无效的,即使当前的对象没有then(),还是会被识别为thenable。

所以,在编写“鸭子类型”代码时,别忘了先检查原型链。

通过检查thenable,我们可以解决promise中的一些信任问题,promise也提供了一些方法,让我们将thenable彻底变为promise,这样,它的可信任度就变高了。

 

后续如有补充会接着写在这里~~

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值