位置: 编程技术 - 正文

异步JavaScript编程中的Promise使用方法(javascript异步编程)

编辑:rootadmin

推荐整理分享异步JavaScript编程中的Promise使用方法(javascript异步编程),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:js异步方法有哪些,js异步编程的四种方法,js异步实现原理,js异步编程原理,js异步编程的四种方法,js异步实现原理,js异步编程的四种方法,js异步编程的四种方法,内容如对您有帮助,希望把文章链接给更多的朋友!

异步?

我在很多地方都看到过异步(Asynchronous)这个词,但在我还不是很理解这个概念的时候,却发现自己常常会被当做“已经很清楚”(* ̄&#; ̄)。

如果你也有类似的情况,没关系,搜索一下这个词,就可以得到大致的说明。在这里,我会对JavaScript的异步做一点额外解释。

看一下这段代码:

这段代码运行后会得到类似Time elapsed: ms这样的结果。 setTimeout()所设定的在未来ms时执行的函数,实际等了比ms更多的时间后才执行。

要如何解释呢?调用setTimeout()时,一个延时事件被排入队列。然后,继续执行这之后的代码,以及更后边的代码,直到没有任何代码。没有任何代码后,JavaScript线程进入空闲,此时JavaScript执行引擎才去翻看队列,在队列中找到“应该触发”的事件,然后调用这个事件的处理器(函数)。处理器执行完成后,又再返回到队列,然后查看下一个事件。

单线程的JavaScript,就是这样通过队列,以事件循环的形式工作的。所以,前面的代码中,是用while将执行引擎拖在代码运行期间长达ms,而在全部代码运行完回到队列前,任何事件都不会触发。这就是JavaScript的异步机制。JavaScript的异步难题

JavaScript中的异步操作可能不总是简单易行的。

Ajax也许是我们用得最多的异步操作。以jQuery为例,发起一个Ajax请求的代码一般是这样的:

这样的写法有什么问题吗?简单来说,不够轻便。为什么一定要在发起请求的地方,就要把success和error这些回调给写好呢?假如我的回调要做很多很多的事情,是要我想起一件事情就跑回这里添加代码吗?

再比如,我们要完成这样一件事:有4个供Ajax访问的url地址,需要先Ajax访问第1个,在第1个访问完成后,用拿到的返回数据作为参数再访问第2个,第2个访问完成后再第3个...以此到4个全部访问完成。按照这样的写法,似乎会变成这样:

你一定会觉得这种称为Pyramid of Doom(金字塔厄运)的代码看起来很糟糕。习惯了直接附加回调的写法,就可能会对这种一个传递到下一个的异步事件感到无从入手。为这些回调函数分别命名并分离存放可以在形式上减少嵌套,使代码清晰,但仍然不能解决问题。

另一个常见的难点是,同时发送两个Ajax请求,然后要在两个请求都成功返回后再做一件接下来的事,想一想如果只按前面的方式在各自的调用位置去附加回调,这是不是好像也有点难办?

适于应对这些异步操作,可以让你写出更优雅代码的就是Promise。Promise上场

Promise是什么呢?先继续以前面jQuery的Ajax请求示意代码为例,那段代码其实可以写成这个样子:

这和前面的Ajax请求示意代码是等效的。可以看到,Promise的加入使得代码形式发生了变化。Ajax请求就好像变量赋值一样,被“保存”了起来。这就是封装,封装将真正意义上让异步事件变得容易起来。封装是有用的

Promise对象就像是一个封装好的对异步事件的引用。想要在这个异步事件完成后做点事情?给它附加回调就可以了,不管附加多少个也没问题!

jQuery的Ajax方法会返回一个Promise对象(这是jQuery1.5重点增加的特性)。如果我有do1()、do2()两个函数要在异步事件成功完成后执行,只需要这样做:

这样可要自由多了,我只要保存这个Promise对象,就在写代码的任何时候,给它附加任意数量的回调,而不用管这个异步事件是在哪里发起的。这就是Promise的优势。正式的介绍

异步JavaScript编程中的Promise使用方法(javascript异步编程)

Promise应对异步操作是如此有用,以至于发展为了CommonJS的一个规范,叫做Promises/A。Promise代表的是某一操作结束后的返回值,它有3种状态:

肯定(fulfilled或resolved),表明该Promise的操作成功了。 否定(rejected或failed),表明该Promise的操作失败了。 等待(pending),还没有得到肯定或者否定的结果,进行中。

此外,还有1种名义上的状态用来表示Promise的操作已经成功或失败,也就是肯定和否定状态的集合,叫做结束(settled)。Promise还具有以下重要的特性:

一个Promise只能从等待状态转变为肯定或否定状态一次,一旦转变为肯定或否定状态,就再也不会改变状态。 如果在一个Promise结束(成功或失败,同前面的说明)后,添加针对成功或失败的回调,则回调函数会立即执行。

想想Ajax操作,发起一个请求后,等待着,然后成功收到返回或出现错误(失败)。这是否和Promise相当一致?

进一步解释Promise的特性还有一个很好的例子:jQuery的$(document).ready(onReady)。其中onReady回调函数会在DOM就绪后执行,但有趣的是,如果在执行到这句代码之前,DOM就已经就绪了,那么onReady会立即执行,没有任何延迟(也就是说,是同步的)。Promise示例生成Promise

Promises/A里列出了一系列实现了Promise的JavaScript库,jQuery也在其中。下面是用jQuery生成Promise的代码:

jQuery自己特意定义了名为Deferred的类,它实际上就是Promise。$.Deferred()方法会返回一个新生成的Promise实例。一方面,使用deferred.done()、deferred.fail()等为它附加回调,另一方面,调用deferred.resolve()或deferred.reject()来肯定或否定这个Promise,且可以向回调传递任意数据。合并Promise

还记得我前文说的同时发送2个Ajax请求的难题吗?继续以jQuery为例,Promise将可以这样解决它:

$.when()方法可以合并多个Promise得到一个新的Promise,相当于在原多个Promise之间建立了AND(逻辑与)的关系,如果所有组成Promise都已成功,则令合并后的Promise也成功,如果有任意一个组成Promise失败,则立即令合并后的Promise失败。级联Promise

再继续我前文的依次执行一系列异步任务的问题。它将用到Promise最为重要的.then()方法(在Promises/A规范中,也是用“有then()方法的对象”来定义Promise的)。代码如下:

Promise的.then()方法的完整形式是.then(onDone, onFail, onProgress),这样看上去,它像是一个一次性就可以把各种回调都附加上去的简便方法(.done()、.fail()可以不用了)。没错,你的确可以这样使用,这是等效的。

但.then()方法还有它更为有用的功能。如同then这个单词本身的意义那样,它用来清晰地指明异步事件的前后关系:“先这个,然后(then)再那个”。这称为Promise的级联。

要级联Promise,需要注意的是,在传递给then()的回调函数中,一定要返回你想要的代表下一步任务的Promise(如上面代码的$.ajax(url2, data))。这样,前面被赋值的那个变量才会变成新的Promise。而如果then()的回调函数返回的不是Promise,则then()方法会返回最初的那个Promise。

应该会觉得有些难理解?从代码执行的角度上说,上面这段带有多个then()的代码其实还是被JavaScript引擎运行一遍就结束。但它就像是写好的舞台剧的剧本一样,读过一遍后,JavaScript引擎就会在未来的时刻,依次安排演员按照剧本来演出,而演出都是异步的。then()方法就是让你能写出异步剧本的笔。将Promise用在基于回调函数的API

前文反复用到的$.ajax()方法会返回一个Promise对象,这其实只是jQuery特意提供的福利。实际情况是,大多数JavaScript API,包括Node.js中的原生函数,都基于回调函数,而不是基于Promise。这种情况下使用Promise会需要自行做一些加工。

这个加工其实比较简单和直接,下面是例子:

这样,将Promise的肯定或否定的触发器,作为API的回调传入,就变成了Promise的处理模式了。Promise是怎么实现出来的?

本文写Promise写到这里,你发现了全都是基于已有的实现了Promise的库。那么,如果要自行构筑一个Promise的话呢?

位列于Promises/A的库列表第一位的Q可以算是最符合Promises/A规范且相当直观的实现。如果你想了解如何做出一个Promise,可以参考Q提供的设计模式解析。

限于篇幅,本文只介绍Promise的应用。我会在以后单独开一篇文章来详述Promise的实现细节。

作为JavaScript后续版本的ECMAScript 6将原生提供Promise,如果你想知道它的用法,推荐阅读JavaScript Promises: There and back again。结语

Promise这个词顽强到不适合翻译,一眼之下都会觉得意义不明。不过,在JavaScript里做比较复杂的异步任务时,它的确可以提供相当多的帮助。

举例讲解Node.js中的Writable对象 只要有玩过nodejs,那就一定接触过Writable。http模块的请求回调参数中的res参数就是一个Writable对象。我们经常会往上面write一堆东西,最后调用个end方法

node.js操作mysql(增删改查) 最近这段时间研究Node感觉不错,自己做了一个增删改查,虽然有些简陋,但是思想是想通的,其实所有项目都是增删改查,有助于初学者快速掌握Node首

windows下安装nodejs及框架express 以下通过两种方式介绍windows下安装node.js及框架express第一种方式:总共分为四步轻松完成Nodejs的Express安装第一步、安装所有要先按装express-generator,否

标签: javascript异步编程

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

上一篇:AngularJS+Node.js实现在线聊天室(angular.min.js)

下一篇:举例讲解Node.js中的Writable对象(举例讲解生产可能性曲线)

  • 城建税的计税依据是增值税和消费税的和吗
  • 查询一般纳税人资格证明
  • 持有至到期投资核算内容
  • 存在弃置费用的固定资产的财务费用
  • 委托外单位研发的研发费用加计扣除最新政策
  • 管理费用借贷方都有,如何结转
  • 新公司开账户需要多少钱
  • 咨询公司所得税税负率是多少合适
  • 送现金券用什么活动语
  • 出租不动产房屋交什么税
  • 财产转让应纳税额如果是负数怎么办
  • 工会差旅费如何做账
  • 补发工资计算公式
  • 扶贫费用事业单位账务处理怎么做?
  • 银行利息回单怎么打印
  • 固定资产期初余额在哪里录入
  • 船期延迟出口开票开在了上个月会计处理是怎样的?
  • 非正常损失进项税额怎么处理
  • 外商投资企业母公司派到境内职员回国后
  • 差错更正要调去年的吗
  • 企业支付劳务费到底需要发票吗
  • 蔬菜批发公司销售蔬菜是否免税
  • 中意装饰工程有限公司怎么样
  • 商品流通企业进货费用金额较小的计入什么科目
  • 应收账款及票据
  • 增值税预缴税款表
  • 忘了结转成本怎么办
  • 资产减值损失月末需要结转吗
  • 增值税查补税款可以开发票吗
  • 顶账的固定资产怎么入账
  • vue中的...
  • 如何做无票收入的会计分录
  • 运输公司的进项必须是专票吗
  • 直接人工分配按计时工资怎么分
  • vue slot标签
  • win11怎么添加字体到个性化
  • PHP:oci_field_is_null()的用法_Oracle函数
  • 大城遗址公园
  • 应付账款挂账会计分录
  • 一次摊销法计算公式
  • 微信小程序开发零基础入门
  • 尚融资本
  • vue入门
  • gcn时间序列
  • 损益类科目增加记借方吗
  • mysql的where语句优化
  • 加工企业的税怎么算
  • 公司收到保险公司赔款后又转给个人怎么处理
  • 跨季度的发票可以冲红吗
  • 应付账款坏账损失的会计分录
  • 小规模纳税人是简易计税还是一般计税
  • 广告费明细清单
  • 母公司与子公司内部合作协议
  • 借贷记账法的记账依据是什么
  • 预缴增值税后税款怎么算
  • 房企预收款如何缴纳企业所得税
  • 库存商品结转成本是什么意思
  • 收到美元收入如何入账
  • 帮别人加工需要什么手续
  • 年末本年利润没有结转影响报税吗
  • 纳税人id
  • 未分配利润是净利润吗
  • win10系统详情
  • freebsd版本
  • win10相机模糊
  • 怎么修改win10登录名
  • perl主要用处
  • perl脚本执行顺序
  • cocos设置锚点
  • cocos2dx游戏开发
  • win7支持快速启动吗
  • 批量安装windows7补丁
  • easyui控件
  • android开发app
  • js-cookie vue
  • bootstrap按钮的风格有哪些?
  • 入户走访时宣传内容
  • 大同县税务局
  • 公司汽车用油计入什么科目
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设