位置: 编程技术 - 正文

理解javascript异步编程(js的异步解决方案有哪些)

编辑:rootadmin

推荐整理分享理解javascript异步编程(js的异步解决方案有哪些),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:javascript异常,简述javascript的异常处理机制,javascript的理解,js异常处理语句,使用js处理异步有哪些方式,js的异步解决方案有哪些,js的异步解决方案有哪些,javascript异常,内容如对您有帮助,希望把文章链接给更多的朋友!

一、异步机制

JavaScript的执行环境是单线程的,单线程的好处是执行环境简单,不用去考虑诸如资源同步,死锁等多线程阻塞式编程等所需要面对的恼人的问题。但带来的坏处是当一个任务执行时间较长时,后面的任务会等待很长时间。在浏览器端就会出现浏览器假死,鼠标无法响应等情况。所以在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应。所谓异步执行,不同于同步执行(程序的执行顺序与任务的排列顺序是一致的、同步的),每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。既然Javascript是单线程的,那它又如何能够异步的执行呢?

二、Javascript线程模型和事件驱动

JavaScript有一个基于事件循环的并发模式。这个模式与C语言和java有很大不同。

运行时的概念

栈函数调用形成堆栈帧。

当调用函数g时,创建第一个包含g参数和局部变量的帧。当g函数调用f函数时,创建包含f参数和局部变量第二个堆栈帧并推到第一个堆栈帧的顶部。当f返回时,顶部的堆栈帧元素被弹出(只留下g调用)。当g函数返回时,堆栈为空。

堆堆是一个大型的非结构化区域,对象被分配到堆中。队列一个javascript运行环境包含一个信息队列,这个队列是一系列将被执行的信息列表。每一个消息被关联到一个函数上。当堆栈为空时,从消息队列中取出一个消息并进行处理。该处理包含调用相关的函数(以及因此产生一个初始化的堆栈帧)。当堆栈再次为空时,消息处理结束。事件循环

事件循环的名字源于它的实现,经常像下面这样:

queue.waitForMessage同步等待一个消息。

1、运行到完成每个消息完全处理之后,其它消息才会被处理。这样的好处就是当一个函数不能被提前,只能等其他函数执行完毕(并且可以修改数据的函数操作)。这不同于C,例如,如果一个函数在一个线程运行时,它可以停在任何点运行在另一个线程一些其他的代码。这种模式的缺点是,如果一个消息时间过长完成,Web应用程序无法处理像点击或滚动的用户交互。该浏览器可缓解此与“脚本花费的时间太长运行”对话框。一个很好的做法,遵循的是使信息处理短,如果可能削减一个消息到几条消息。2、添加消息在网页浏览器中,事件可以在任何时候添加,一个事件发生并伴随事件监听绑定到事件上。如果没有事件监听,则事件丢失。就像点击一个元素,元素上绑定点击事件。调用setTimeout时,当函数的第二个参数时间被传递进去,将添加一个消息到队列中。如果在队列中没有其他消息,该消息被立即处理;然而,如果有消息,则setTimeout的信息将必须等待其它消息以进行处理。由于这个原因,第二个参数是最小的时间,而不是一个保证时间。3、几个运行环境之间的通信一个web worker或跨域iframe都有自己的堆栈,堆,和消息队列。两个不同的运行环境只能通过postMessage的方法发送消息进行通信。这种方法增加了一个消息到其他运行时,如果后者监听消息事件。从不阻塞

事件循环模型是javascript的一个很有意思的属性,不像其它语言,它从不阻塞。假定浏览器中有一个专门用于事件调度的实例(该实例可以是一个线程,我们可以称之为事件分发线程event dispatch thread),该实例的工作就是一个不结束的循环,从事件队列中取出事件,处理所有很事件关联的回调函数(event handler)。注意回调函数是在Javascript的主线程中运行的,而非事件分发线程中,以保证事件处理不会发生阻塞。通过事件和回调的I/O操作是一个典型的表现,所以当应用等待索引型数据库查询返回或XHR请求返回时,它仍然可以处理其他事情比如用户输入。

三、回调

回调是javascript的基础,函数被作为参数进行传递。像下面:

如果f1中执行了大量的耗时操作,而且f2需要在f1之后执行。则程序可以改为回调的形式。如下:

理解javascript异步编程(js的异步解决方案有哪些)

运行结果:

采用这种方式,我们把同步操作变成了异步操作,f1不会堵塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行。回调函数的优点是简单,轻量级(不需要额外的库)。缺点是各个部分之间高度耦合(Coupling),流程会很混乱,而且每个任务只能指定一个回调函数。某个操作需要经过多个非阻塞的IO操作,每一个结果都是通过回调,产生意大利面条式(spaghetti)的代码。

四、事件监听

另一种思路是采用事件驱动模式。任务的执行不取决于代码的顺序,而取决于某个事件是否发生。

也可以自定义事件进行监听,关于自定义事件,属于另外一部分的内容。这种方法的优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以"去耦合"(Decoupling),有利于实现模块化。缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。

五、观察者模式

我们假定,存在一个"信号中心",某个任务执行完成,就向信号中心"发布"(publish)一个信号,其他任务可以向信号中心"订阅"(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做"发布/订阅模式"(publish-subscribe pattern),又称"观察者模式"(observer pattern)。

上面代码的运行结果为:

观察者模式的实现方法有很多种,也可以直接借用第三方库。这种方法的性质与"事件监听"类似(观察者模式和自定义事件非常相似),但是明显优于后者。观察者模式和事件监听一样具有良好的去耦性,并且有一个消息中心,通过对消息中心的处理,可以良好地监控程序运行。

六、Promises对象

Promises的概念是由CommonJS小组的成员在 Promises/A规范 中提出来的。Promises被逐渐用作一种管理异步操作回调的方法,但出于它们的设计,它们远比那个有用得多。Promise允许我们以同步的方式写代码,同时给予我们代码的异步执行。

上面代码的运行结果为:

上面引用的是jquery对Promises/A的实现,jquery中还有一系列方法,具体可参考:Deferred Object.关于Promises,强烈建议读一下You're Missing the Point of Promises.还有很多第三方库实现了Promises,如:Q、Bluebird、 mmDeferred 等。Promise(中文:承诺)其实为一个有限状态机,共有三种状态:pending(执行中)、fulfilled(执行成功)和rejected(执行失败)。其中pending为初始状态,fulfilled和rejected为结束状态(结束状态表示promise的生命周期已结束)。状态转换关系为:pending->fulfilled,pending->rejected。随着状态的转换将触发各种事件(如执行成功事件、执行失败事件等)。 下节具体讲述状态机实现js异步编程。

七、状态机

Promises的本质实际就是通过状态机来实现的,把异步操作与对象的状态改变挂钩,当异步操作结束的时候,发生相应的状态改变,由此再触发其他操作。这要比回调函数、事件监听、发布/订阅等解决方案,在逻辑上更合理,更易于降低代码的复杂度。关于Promises可参考:JS魔法堂:剖析源码理解Promises/A规范 。

八、ES6对异步的支持

这是一个新的技术,成为年的ECMAScript(ES6)标准的一部分。该技术的规范已经完成,但实施情况在不同的浏览器不同,在浏览器中的支持情况如下。

以上代码在Chrome 版本中的运行结果为:

标签: js的异步解决方案有哪些

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

上一篇:js实现的鼠标滚轮滚动切换页面效果(类似360默认页面滚动切换效果)(js鼠标滚轮缩放)

下一篇:用window.onerror捕获并上报Js错误的方法(windows捕获文件夹)

  • 个体工商户核定征收
  • 认证不过的进项税是怎么调出分录?
  • 建筑服务增值税税率
  • 中国注册税务师考试时间
  • 补缴关税税率
  • 房地产企业所得税纳税义务发生时间
  • 增值税专用发票抵扣期限
  • 个体季度申报怎么写
  • 机耕道属于水利还是土地整治
  • 纳税人等级怎么划分
  • 如何合理把公司的钱拿出来
  • 水资源税怎么入账
  • 新会计准则土地使用权摊销处理
  • 分期收款销售货物 收入确认
  • 注销税务登记申请书
  • 企业租赁集体土地种植经济林如何补偿
  • 少提的税金如何做账
  • 销售折扣购货方的会计分录
  • 简易计税项目的分包款为建筑服务劳务费,可以扣除吗
  • 计提房租的会计科目
  • 企业所得税税前扣除政策
  • 牵引车需要交车船税吗
  • 回迁房怎么交税
  • 应收票据借方表示负债吗
  • 2008版增值税普通发票图片
  • 2019年水利部
  • 专项资金需要交印花税吗
  • 无发票的支出如何入账
  • 一般纳税人十万以下免教育费附加
  • 收获怎么理解
  • 税金及附加包括个人所得税吗
  • 增值税的特殊销售方式有哪些?税务处理时怎样的?
  • symtray.exe - symtray是什么进程 有何作用
  • 政府补助调增还是调减
  • 收到的投资属于什么科目
  • php统计当前在线人数
  • iphone6s显示4g却无法上网
  • 吊兰怎么养才能开花
  • 详解php实现执行任务
  • php的什么函数可以判断变量是否存在
  • 公允价值进行会计计量
  • php的laravel框架答辩
  • php面向对象是什么意思
  • 【torch.nn.Parameter 】参数相关的介绍和使用
  • python机器人编程控制
  • 电子发票手动导出到哪
  • 激活接口的命令
  • 销货退回与折让属于什么科目
  • 投标保证金属于什么费用
  • 代开专票时缴纳的增值税账务处理如何做?
  • 织梦官方
  • 公对私转账没有到账怎么查询
  • 关联方计提坏账准备如何规定
  • 借应付职工薪酬贷财政拨款收入
  • 资本公积溢价转增
  • 小规模纳税人免税政策
  • 权益法核算投资收益纳税调整
  • 应交增值税进项税额月底怎么处理
  • 预缴税款留抵是什么意思
  • 建筑公司需要什么人员
  • 车子报废车子怎么处理
  • 注册表已被管理员禁用怎么处理
  • windows8.1开机
  • win10系统怎么连接蓝牙
  • ubuntu添加环境变量后黑屏
  • win8系统中向日葵软件造成的屏幕亮度无法调节怎么办?
  • 2014 ChinaJoy落下帷幕 十大年度热门事件盘点
  • 绘制多边形工具使用方法
  • jquery validate表单内容怎么添加边框
  • jQuery基于ajax操作json数据简单示例
  • shell 输出
  • html竖排改为横排
  • python 堆叠
  • 从零开始学什么技术
  • 深入python3
  • python3.7怎么安装pil
  • jQuery easyUI datagrid 增加求和统计行的实现代码
  • 建筑工程合同首付款
  • 张雪峰谈建筑专业
  • 100万元的人民币
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设