位置: 编程技术 - 正文

理解JavaScript中Promise的使用(js prev())

编辑:rootadmin

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

文章相关热门搜索词:js中prompt,js中pre是什么意思,js prev(),javascript中prompt()方法的作用,js中pre是什么意思,javascript中prompt,js中pre是什么意思,javascript中pre,内容如对您有帮助,希望把文章链接给更多的朋友!

Javascript 采用回调函数(callback)来处理异步编程。从同步编程到异步回调编程有一个适应的过程,但是如果出现多层回调嵌套,也就是我们常说的厄运的回调金字塔(Pyramid of Doom),绝对是一种糟糕的编程体验。于是便有了 CommonJS 的 Promises/A 规范,用于解决回调金字塔问题。本文先介绍 Promises 相关规范,然后再通过解读一个迷你的 Promises 以加深理解。

什么是 Promise一个 Promise 对象代表一个目前还不可用,但是在未来的某个时间点可以被解析的值。它允许你以一种同步的方式编写异步代码。例如,如果你想要使用 Promise API 异步调用一个远程的服务器,你需要创建一个代表数据将会在未来由 Web 服务返回的 Promise 对象。唯一的问题是目前数据还不可用。当请求完成并从服务器返回时数据将变为可用数据。在此期间,Promise 对象将扮演一个真实数据的代理角色。接下来,你可以在 Promise 对象上绑定一个回调函数,一旦真实数据变得可用这个回调函数将会被调用。

Promise 对象曾经以多种形式存在于许多语言中。

去除厄运的回调金字塔(Pyramid of Doom)Javascript 中最常见的反模式做法是回调内部再嵌套回调。

引入 Promises 之后的代码

Promises 将嵌套的 callback,改造成一系列的.then的连缀调用,去除了层层缩进的糟糕代码风格。Promises 不是一种解决具体问题的算法,而已一种更好的代码组织模式。接受新的组织模式同时,也逐渐以全新的视角来理解异步调用。

各个语言平台都有相应的 Promise 实现

Java's java.util.concurrent.Future Python's Twisted deferreds and PEP- futures F#'s Async .Net's Task C++ 's std::future Dart's Future Javascript's Promises/A/B/D/A+

下面我来相信了解一下 javascript 语言环境下各个规范的一些细节。

Promises/A 规范promise 表示一个最终值,该值由一个操作完成时返回。

promise 有三种状态:**未完成** (unfulfilled),**完成** (fulfilled) 和**失败** (failed)。 promise 的状态只能由**未完成**转换成完成,或者**未完成**转换成**失败** 。 promise 的状态转换只发生一次。

promise 有一个 then 方法,then 方法可以接受 3 个函数作为参数。前两个函数对应 promise 的两种状态 fulfilled 和 rejected 的回调函数。第三个函数用于处理进度信息(对进度回调的支持是可选的)。

如果 promise 支持如下连个附加方法,称之为可交互的 promise

get(propertyName)

获得当前 promise 最终值上的一个属性,返回值是一个新的 promise。

call(functionName, arg1, arg2, ...)

调用当然 promise 最终值上的一个方法,返回值也是一个新的promise。

Promises/B 规范在 Promises/A 的基础上,Promises/B 定义了一组 promise 模块需要实现的 API

when(value, callback, errback_opt)如果 value 不是一个 promise ,那么下一事件循环callback会被调用,value 作为 callback 的传入值。如果 value 是一个 promise,promise 的状态已经完成或者变成完成时,那么下一事件循环 callback 会被调用,resolve 的值会被传入 callback;promise 的状态已经失败或者变成失败时,那么下一事件循环 errback 会被调用,reason 会作为失败的理由传入 errback。

asap(value, callback, errback_opt)与 when 最大的区别,如果 value 不是一个 promise,会被立即执行,不会等到下一事件循环。

enqueue(task Function)尽可能快地在接下来的事件循环调用 task 方法。

get(object, name)返回一个获得对象属性的 promise。

post(object, name, args)返回一个调用对象方法的 promise。

put(object, name, value)返回一个修改对象属性的 promise。

del(object, name)返回一个删除对象属性的 promise。

makePromise(descriptor Object, fallback Function)返回一个 promise 对象,该对象必须是一个可调用的函数,也可能是可被实例化的构造函数。

第一个参数接受一个描述对象,该对象结构如下, 理解JavaScript中Promise的使用(js prev())

上面每一个注册的 handle 都返回一个 resolved value或者 promise。

第二个参数接受一个 fallback(message,...args) 函数,当没有 promise 对象没有找到对应的 handle 时该函数会被触发,返回一个 resolved value 或者 promise。

defer()返回一个对象,该对象包含一个 resolve(value) 方法和一个 promise 属性。当 resolve(value) 方法被第一次调用时,promise 属性的状态变成 完成,所有之前或之后观察该 promise 的 promise 的状态都被转变成 完成。value 参数如果不是一个 promise ,会被包装成一个 promise 的 ref。resolve 方法会忽略之后的所有调用。

reject(reason String)返回一个被标记为 失败 的 promise。一个失败的 promise 上被调用 when(message) 方法时,会采用如下两种方法之一1. 如果存在 errback,errback 会以 reason 作为参数被调用。when方法会将 errback 的返回值返回。2. 如果不存在 errback,when 方法返回一个新的 reject 状态的promise 对象,以同一 reason 作为参数。

ref(value)如果 value 是 promise 对象,返回 value 本身。否则,返回一个resolved 的 promise,携带如下 handle。1. when(errback),忽略 errback,返回 resolved 值2. get(name),返回 resolved 值的对应属性。3. put(name, value) ,设置 resolved 值的对应属性。4. del(name),删除 resolved 值的对应属性。5. post(name, args), 调用 resolved 值的对应方法。6. 其他所有的调用都返回一个 reject,并携带 "Promise does not handle NAME" 的理由。

isPromise(value) Boolean判断一个对象是否是 promise

method(name String)获得一个返回 name 对应方法的 promise。返回值是 "get", "put", "del" 和 "post" 对应的方法,但是会在下一事件循环返回。

Promises/D 规范为了增加不同 promise 实现之间的可互操作性,Promises/D 规范对promise 对象和 Promises/B 规范做了进一步的约定。以达到鸭子类型的效果(Duck-type Promise)。

简单来说Promises/D 规范,做了两件事情,

1、如何判断一个对象是 Promise 类型。2、对 Promises/B 规范进行细节补充。甄别一个 Promise 对象Promise 对象必须是实现 promiseSend 方法。1. 在 promise 库上下文中,如果对象包含 promiseSend 方法就可以甄别为promise 对象2. promiseSend 方法必须接受一个操作名称,作为第一个参数3. 操作名称是一个可扩展的集合,下面是一些保留名称1. when,此时第三个参数必须是 rejection 回调。1. rejection回调必须接受一个 rejection 原因(可以是任何值)作为第一个参数2. get,此时第三个参数为属性名(字符串类型)3. put,此时第三个参数为属性名(字符串类型),第四个参数为新属性值。4. del,此时第三个参数为属性名5. post,此时第三个参数为方法的属性名,接下来的变参为方法的调用参数6. isDef4. promiseSend方法的第二个参数为 resolver 方法5. promiseSend方法可能接受变参6. promiseSend方法必须返回undefined

对 Promises/B 规范的补充Promises/D 规范中对 Promises/B 规范中定义的ref、reject、def、defer方法做了进一步细致的约束,此处略去这些细节。

Promises/A+ 规范前面提到的 Promises/A/B/D 规范都是有CommonJS组织提出的,Promises/A+是有一个自称为Promises/A+ 组织发布的,该规范是以Promises/A作为基础进行补充和修订,旨在提高promise实现之间的可互操作性。

Promises/A+ 对.then方法进行细致的补充,定义了细致的Promise Resolution Procedure流程,并且将.then方法作为promise的对象甄别方法。

此外,Promises/A+ 还提供了兼容性测试工具,以确定各个实现的兼容性。

实现一个迷你版本的Promise上面扯了这么多规范,现在我们看看如何实现一个简单而短小的Promise。

1、状态机

2、状态变迁仅支持两种状态变迁,fulfill和reject

fulfill和reject方法较为底层,通常更高级的resolve方法开放给外部。

resolve方法可以接受一个普通值或者另一个promise作为参数,如果接受一个promise作为参数,等待其完成。promise不允许被另一个promise fulfill,所以需要开放resolve方法。resolve方法依赖一些帮助方法定义如下:

这里resolve和doResolve之间的递归很巧妙,用来处理promise的层层嵌套(promise的value是一个promise)。

构造器

.done方法

.then方法

$.promisejQuery 1.8 之前的版本,jQuery的 then 方法只是一种可以同时调用 done 、fail 和 progress 这三种回调的速写方法,而 Promises/A 规范的 then 在行为上更像是 jQuery 的 pipe。 jQuery 1.8 修正了这个问题,使 then 成为 pipe 的同义词。不过,由于向后兼容的问题,jQuery 的 Promise 再如何对 Promises/A 示好也不太会招人待见。

此外,在 Promises/A 规范中,由 then 方法生成的 Promise 对象是已执行还是已拒绝,取决于由 then 方法调用的那个回调是返回值还是抛出错误。在 JQuery 的 Promise 对象的回调中抛出错误是个糟糕的主意,因为错误不会被捕获。

小结最后一个例子揭示了,实现 Promise 的关键是实现好 doResolve 方法,在完事以后触发回调。而为了保证异步 setTimeout(fun, 0); 是关键一步。

Promise 一直用得蛮顺手的,其很好的优化了 NodeJS 异步处理时的代码结构。但是对于其工作原理却有些懵懂和好奇,于是花了些精力查阅并翻译了Promise 的规范,以充分的理解 Promise 的细节。

标签: js prev()

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

上一篇:基于JavaScript实现鼠标悬浮弹出跟随鼠标移动的带箭头的信息层(javascript基于什么的语言)

下一篇:图片旋转、鼠标滚轮缩放、镜像、切换图片js代码(图片旋转鼠标键盘怎么弄)

  • 个人私活 要交个人所得税吗
  • 以前年度调整损益借方表示什么
  • 缴纳的工会经费收据怎么取得
  • 财务报表审计的标准
  • 收到货款没开票做应收还还应付
  • 物业费的税金是否向业主收取
  • 增值税和个人所得税都要交吗
  • 先出货后开票
  • 进项税额销项税额月末需要结转吗
  • 国税征收项目有哪些
  • 股东溢价转让股份交易市场会计分录
  • 发票丢了企业所得怎么办
  • 多付银行承兑退回的会计分录怎么写?
  • 福利费进项税可以抵扣
  • 工会专户收到职工福利经费会计处理怎么做?
  • 铁路运输专用发票印花税处理
  • 房产税细节
  • 中国银行结算包括哪些内容?怎么做会计分录?
  • 购进免税农产品怎么计算进项税额
  • 买了两个月社保能用多少医药费
  • 个人独资企业改为有限公司
  • 详细解读财税[2014]75号文件
  • 劳务公司开劳务费发票怎么开,税率是多少
  • 公司买汽车怎么做内账
  • 月末印花税会计分录
  • 美团扣点怎么做凭证
  • 应收账款账龄分析简单例题
  • 财务费用错记制造费用
  • 个体工商户交企业所得
  • 红冲的普通发票要给对方吗
  • 支付装修押金会退吗
  • win10任务栏图标怎么变大
  • 应收账款记账凭证如何填写
  • 小规模购进商品只收到记账联专票
  • 腾讯云centos5.8
  • 政府回购企业土地
  • 收到员工罚款分录怎么记账
  • 公司注销做账
  • 营改增后房租收入怎么交税
  • 高新技术企业研究开发费用加计扣除
  • linux子网掩码自动变成24
  • 路由器增强型
  • 税盘可以全额抵扣是什么意思
  • 物业公司购买空调合法吗
  • python3 字典遍历
  • 理财产品利息计算方法
  • 金蝶现金流量表不对怎么处理
  • 融资租赁方式的条件
  • 公司成立开的户叫什么
  • 外购豆油给送客户好吗
  • 企业收到退税款在年报怎么填
  • 材料采购和原材料和在途物资的区别
  • 出口退税的会计科目
  • 报废资产处置账务处理
  • 委托出口由谁办理退税
  • 永续债利息可以抵税吗
  • 支付给个人的劳务费需要发票吗
  • 办公用品怎么开大额发票
  • sql server 自增列设置语句
  • linux系统rm -rf
  • 系统图工具
  • Win10 RedStone 2预览版14936快速版开始推送
  • os x10.11el capitan beta5更新了什么?os x10.11el capitan beta5下载地址
  • win7系统IE浏览器打开跳转到360浏览器,怎么阻止
  • kernel32在哪个文件夹
  • win10系统怎么刻录光盘?win10刻录光盘详细图文步骤
  • linux必会的20种服务
  • 怎么检测端口通不通
  • javascript从入门到放弃
  • php常用函数200个
  • javascript密码框
  • js面向对象是什么意思
  • ruby元编程第二版
  • 新中国税务历史
  • 税控盘时间不对有影响吗
  • 在山东省一个月水费大概多少
  • 同比减少怎么计算出来
  • 上海长宁区多大面积
  • 企业税务情况查询
  • 单位固定资产转到个人名下要交税吗
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设