位置: 编程技术 - 正文

详细解读JavaScript编程中的Promise使用(详细解读了)

编辑:rootadmin

推荐整理分享详细解读JavaScript编程中的Promise使用(详细解读了),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:详细解读了,详细解读是什么意思,详细解读退役军人优待政策,详细解读是什么意思,详细解读了,详细解读富士康Model B官图,详细解读是什么意思,详细解读富士康Model B官图,内容如对您有帮助,希望把文章链接给更多的朋友!

Promise核心说明

尽管Promise已经有自己的规范,但目前的各类Promise库,在Promise的实现细节上是有差异的,部分API甚至在意义上完全不同。但Promise的核心内容,是相通的,它就是then方法。在相关术语中,promise指的就是一个有then方法,且该方法能触发特定行为的对象或函数。

Promise可以有不同的实现方式,因此Promise核心说明并不会讨论任何具体的实现代码。

先阅读Promise核心说明的意思是:看,这就是需要写出来的结果,请参照这个结果想一想怎么用代码写出来吧。起步:用这一种方式理解Promise

回想一下Promise解决的是什么问题?回调。例如,函数doMission1()代表第一件事情,现在,我们想要在这件事情完成后,再做下一件事情doMission2(),应该怎么做呢?

先看看我们常见的回调模式。doMission1()说:“你要这么做的话,就把doMission2()交给我,我在结束后帮你调用。”所以会是:

Promise模式又是如何呢?你对doMission1()说:“不行,控制权要在我这里。你应该改变一下,你先返回一个特别的东西给我,然后我来用这个东西安排下一件事。”这个特别的东西就是Promise,这会变成这样:

可以看出,Promise将回调模式的主从关系调换了一个位置(翻身做主人!),多个事件的流程关系,就可以这样集中到主干道上(而不是分散在各个事件函数之内)。

好了,如何做这样一个转换呢?从最简单的情况来吧,假定doMission1()的代码是:

那么,它可以改变一下,变成这样:

这就完成了转换。虽然并不是实际有用的转换,但到这里,其实已经触及了Promise最为重要的实现要点,即Promise将返回值转换为带then方法的对象。进阶:Q的设计路程从defer开始

design/q0.js是Q初步成型的第一步。它创建了一个名为defer的工具函数,用于创建Promise:

这段源码可以看出,运行defer()将得到一个对象,该对象包含resolve和then两个方法。请回想一下jQuery的Deferred(同样有resolve和then),这两个方法将会是近似的效果。then会参考pending的状态,如果是等待状态则将回调保存(push),否则立即调用回调。resolve则将肯定这个Promise,更新值的同时运行完所有保存的回调。defer的使用示例如下:

oneOneSecondLater().then(callback);

这里oneOneSecondLater()包含异步内容(setTimeout),但这里让它立即返回了一个defer()生成的对象,然后将对象的resolve方法放在异步结束的位置调用(并附带上值,或者说结果)。

到此,以上代码存在一个问题:resolve可以被执行多次。因此,resolve中应该加入对状态的判断,保证resolve只有一次有效。这就是Q下一步的design/q1.js(仅差异部分):

对第二次及更多的调用,可以这样抛出一个错误,也可以直接忽略掉。分离defer和promise

在前面的实现中,defer生成的对象同时拥有then方法和resolve方法。按照定义,promise关心的是then方法,至于触发promise改变状态的resolve,是另一回事。所以,Q接下来将拥有then方法的promise,和拥有resolve的defer分离开来,各自独立使用。这样就好像划清了各自的职责,各自只留一定的权限,这会使代码逻辑更明晰,易于调整。请看design/q3.js:(q2在此跳过)

如果你仔细对比一下q1,你会发现区别很小。一方面,不再抛出错误(改为直接忽略第二次及更多的resolve),另一方面,将then方法移动到一个名为promise的对象内。到这里,运行defer()得到的对象(就称为defer吧),将拥有resolve方法,和一个promise属性指向另一个对象。这另一个对象就是仅有then方法的promise。这就完成了分离。

前面还有一个isPromise()函数,它通过是否有then方法来判断对象是否是promise(duck-typing的判断方法)。为了正确使用和处理分离开的promise,会像这样需要将promise和其他值区分开来。实现promise的级联

详细解读JavaScript编程中的Promise使用(详细解读了)

接下来会是相当重要的一步。到前面到q3为止,所实现的promise都是不能级联的。但你所熟知的promise应该支持这样的语法:

以上过程可以理解为,promise将可以创造新的promise,且取自旧的promise的值(前面代码中的value)。要实现then的级联,需要做到一些事情:

then方法必须返回promise。 这个返回的promise必须用传递给then方法的回调运行后的返回结果,来设置自己的值。 传递给then方法的回调,必须返回一个promise或值。

design/q4.js中,为了实现这一点,新增了一个工具函数ref:

这是在着手处理与promise关联的value。这个工具函数将对任一个value值做一次包装,如果是一个promise,则什么也不做,如果不是promise,则将它包装成一个promise。注意这里有一个递归,它确保包装成的promise可以使用then方法级联。为了帮助理解它,下面是一个使用的例子:

你可以看到value是怎样传递的,promise级联需要做到的也是如此。

design/q4.js通过结合使用这个ref函数,将原来的defer转变为可级联的形式:

原来callback(value)的形式,都修改为value.then(callback)。这个修改后效果其实和原来相同,只是因为value变成了promise包装的类型,会需要这样调用。

then方法有了较多变动,会先新生成一个defer,并在结尾处返回这个defer的promise。请注意,callback不再是直接取用传递给then的那个,而是在此基础之上增加一层,并把新生成的defer的resolve方法放置在此。此处可以理解为,then方法将返回一个新生成的promise,因此需要把promise的resolve也预留好,在旧的promise的resolve运行后,新的promise的resolve也会随之运行。这样才能像管道一样,让事件按照then连接的内容,一层一层传递下去。加入错误处理

promise的then方法应该可以包含两个参数,分别是肯定和否定状态的处理函数(onFulfilled与onRejected)。前面我们实现的promise还只能转变为肯定状态,所以,接下来应该加入否定状态部分。

请注意,promise的then方法的两个参数,都是可选参数。design/q6.js(q5也跳过)加入了工具函数reject来帮助实现promise的否定状态:

它和ref的主要区别是,它返回的对象的then方法,只会取第二个参数的errback来运行。design/q6.js的其余部分是:

这里的主要改动是,将数组pending只保存单个回调的形式,改为同时保存肯定和否定的两种回调的形式。而且,在then中定义了默认的肯定和否定回调,使得then方法满足了promise的2个可选参数的要求。

你也许注意到defer中还是只有一个resolve方法,而没有类似jQuery的reject。那么,错误处理要如何触发呢?请看这个例子:

可以看出,每一个传递给then方法的返回值是很重要的,它将决定下一个then方法的调用结果。而如果像上面这样返回工具函数reject生成的对象,就会触发错误处理。融入异步

终于到了最后的design/q7.js。直到前面的q6,还存在一个问题,就是then方法运行的时候,可能是同步的,也可能是异步的,这取决于传递给then的函数(例如直接返回一个值,就是同步,返回一个其他的promise,就可以是异步)。这种不确定性可能带来潜在的问题。因此,Q的后面这一步,是确保将所有then转变为异步。

design/q7.js定义了另一个工具函数enqueue:

显然,这个工具函数会将任意函数推迟到下一个事件队列运行。

design/q7.js其他的修改点是(只显示修改部分):

即把原来的value.then的部分,都转变为异步。

到此,Q提供的Promise设计原理q0~q7,全部结束。结语

即便本文已经是这么长的篇幅,但所讲述的也只到基础的Promise。大部分Promise库会有更多的API来应对更多和Promise有关的需求,例如all()、spread(),不过,读到这里,你已经了解了实现Promise的核心理念,这一定对你今后应用Promise有所帮助。

在我看来,Promise是精巧的设计,我花了相当一些时间才差不多理解它。Q作为一个典型Promise库,在思路上走得很明确。可以感受到,再复杂的库也是先从基本的要点开始的,如果我们自己要做类似的事,也应该保持这样的心态一点一点进步。

深入学习JavaScript中的Rest参数和参数默认值 本文将讨论使JavaScript函数更有表现力的两个特性:Rest参数和参数默认值。Rest参数通常,我们需要创建一个可变参数的函数,可变参数是指函数可以接

详解JavaScript ES6中的模板字符串 在ES6中引入了一种新的字符串字面量—模板字符串,除了使用反引号(`)表示,它们看上去和普通的字符串没有什么区别。在最简单的情况下,他们就是

详解JavaScript ES6中的Generator 今天讨论的新特性让我非常兴奋,因为这个特性是ES6中最神奇的特性。这里的神奇意味着什么呢?对于初学者来说,该特性与以往的JS完全不同,甚至有

标签: 详细解读了

本文链接地址:https://www.jiuchutong.com/biancheng/377567.html 转载请保留说明!

上一篇:深入解读JavaScript中的Iterator和for-of循环(深入解读我本是高山)

下一篇:深入学习JavaScript中的Rest参数和参数默认值(深入学习习总书记系列讲话精神)

  • 财税2019 21号第二条
  • 结转未交增值税会计科目怎么写
  • 不是公司的车能抵扣进项吗
  • 内账需要哪些单据
  • 什么是进项加计扣除
  • 边际贡献总额分析法的收入为零
  • 利息收入属于主体收入吗
  • 软件即征即退的发票怎么开
  • 反写了可以重新申报吗
  • 残保金申报在哪申报
  • 已经勾选确认的发票可以取消认证吗
  • 先分后合是什么意思
  • 增值税销项税额在借方还是贷方
  • 财务费用过多有什么影响
  • 电子凭证是否具有法律效力
  • 非居民企业所得税计算公式
  • 股东转账实收资本怎么填
  • 航天信息的服务费
  • 应交所得税的计算例题
  • 一般纳税人两费减免会计分录
  • 企业发生的运输费用怎么做账?
  • 收到保险公司退款
  • 分期付款的车怎么做分录
  • 上年工资计提多了才发现
  • 财会报告需要哪些证书
  • 金融企业哪些呆账损失可以在税前扣除?
  • 增值税普通发票怎么开
  • 当月未出账费用
  • 所得税汇算清缴退税会计分录怎么做
  • m1 mac 恢复出厂
  • 电脑管家游戏加速怎么卸载
  • 财政拨款收入的预算会计科目
  • linux命令df -h结果详解
  • windows10闹钟不响
  • 注销企业基本户需要先注销一般户吗
  • 斯塔尔德
  • 非货币性资产交换
  • vue-router.esm.js?a12b:2046 Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation
  • promise async区别
  • 资产负债表应交税费计算公式
  • websocket()
  • word2vec使用方法
  • vue3 响应式ui框架
  • trace命令详解
  • 帝国cms phpcms
  • 预缴分包抵扣,所有分包都可以抵扣吗
  • 开具红字增值税专用发票信息表在哪
  • 资产类账户有哪些
  • 科研项目财政拨款怎么算
  • 经营结余和事业结余
  • mysql innodb锁
  • 增值税最高开票限额
  • 结转本年利润要算期初余额吗
  • 会计凭证借贷方哪个是收入
  • 个人工资怎么合理避税有什么方法
  • 当月发生业务下月开票如何做账
  • 铁路运输印花税按什么比例交
  • 企业凭证处理流程图
  • 施工方怎么开发票
  • 发票专用章刻制
  • 解析关于sql语句的实现
  • mysql分表命令
  • win10收不到短信验证码
  • windows8禁用uac
  • cmd命令 cd
  • 电脑bios怎么设置usb启动
  • mac的浏览记录在哪儿
  • .exe是什么意思
  • centos 发行版
  • win7开机一直显示配置windows请勿关机怎么办
  • 骨骼动画原理
  • 用正则表达式替换掉两汉字间的括号
  • jquery是基于java的吗
  • js日历插件日期选择器
  • jquery删除dom
  • 组织收入原则三个务必
  • 河南农村社保查询个人账户查询系统
  • 国家税务总局并入财政部最新消息
  • 豫事办登录时密码叫重置什么原因
  • 广东省电子税务局app下载官网
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设