阿里巴巴前端工程师逸翾对JavaScript中的异步编程进行了详细讲解。JavaScript的特点就是单线程,本文首先对单线程异步的原理进行了解读,接着着重分析了JavaScript异步解决方案,详述了Callback、Promise、Generator、Async/Await的特性和使用原理。
你所需要的网站建设服务,我们均能行业靠前的水平为你提供.标准是产品质量的保证,主要从事成都网站制作、网站建设、外贸网站建设、企业网站建设、移动网站建设、网页设计、高端网站设计、网页制作、做网站、建网站。创新互联公司拥有实力坚强的技术研发团队及素养的视觉设计专才。
以下是精彩视频内容整理:
单线程异步
JavaScript语言的一大特点就是单线程,在某个特定的时刻只有特定的代码能够被执行,并阻塞其它的代码,也就是说,同一个时间只能做一件事。
常用的异步操作最主要有网络请求,请求会有响应时间,在响应结果回来之前要处理其它事情;IO操作,比如读取某个文件,在此过程中做其它事情;定时函数。
异步是由浏览器的两个或以上常驻线程共同完成,列如异步请求:JS执行线程发起异步请求,浏览器开一条新的http请求来执行请求,当监视到请求已完成,它会把函数插入到JS执行队列的尾部等待处理。
通过如图所示定时函数实例,可以看出异步处理过程。先是打印一个1,然后执行setTimeout函数,约定在0秒后再打印一个2,然后打印一个3,执行结果为先打印1,再打印3,***再打印2,说明整个过程已经发生异步过程。
Javascript有一个主要的执行主线程,但是setTimeout、IO操作、网络异步请求等都会有一个回调函数,这些操作都是通过浏览器API实现的,当定时器时间到了或者请求结果回来时,会将回调函数push到一个javascript任务队列中,当javascript主线程任务执行完毕后,才会从任务队列中继续拿等待代码再执行。具体流程总结如下:
所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
主线程不断重复上面的第三步。
异步解决方案
了解了Javascript单线程与异步关系,如何书写日常工作中的工程代码呢?怎样能在异步请求结束后执行特定方法?目前,javascript异步编程经历了几个阶段,且在不断演进。
Callback
最开始是回调函数,当事件完成后执行回调函数,相当于完成异步操作。我们可以像使用变量一样使用函数,作为另一个函数的参数,在另一个函数中作为返回结果,在另一个函数中调用它。当我们作为参数传递一个回调函数给另一个函数时,我们只传递了这个函数的定义,并没有在参数中执行它。当函数拥有了在参数中定义的回调函数后,它可以在任何时候调用(也就是回调)它。
我们在工作中最长接触的就是发送Ajax异步请求,在***个请求发送完后,用它的参数处理第二个请求,再用第二个请求的参数请求第三个,三层嵌套代码如图所示。
如图所示为mongoDB在node.js中的实例,嵌套了六层。当多个异步事务多级依赖时,回调函数会形成多级的嵌套,代码变成金字塔型结构。虽然能解决异步问题,但这使得代码得看难懂,更使得调试、重构的过程充满风险。
Promise
Promise比传统解决方案更加合理和强大,是更加好的异步解决方案,promise对象有以下四个特点:
如图所示,左侧创建promise对象,隔2000秒后执行,***返回promise对象。Promise有立即执行性,当创建完对象后,在已完成或已拒绝之前代码都会执行一遍。右侧为打印结果,可以看到创建promise对象被打印出来,并成功生成promise对象,当执行then时,此时已经返回成功状态,所以一直执行成功的回调函数。
那么,promise如何解决异步问题的呢?又有哪些特点呢?具体如下:
代码看起来更加符合逻辑、可读性更强。
Promise并没有改变JS异步执行的本质,从写法上甚至还能看到一点点callback的影子。
如图所示为链式调用方式,***个请求成功后,就去执行下一个,如果任何一个请求未成功,直接catch掉error,并打印出来。
Generator
我们希望以同步方式写异步代码,可以使逻辑更加清晰,代码量减少更多。为了实现这种目标,我们又演进出generator解决方案。
Generator函数很特殊,理解起来比promise和callback更加难,从语法上将,generator具备以下特质:
如图所示,首先定义了test=add(5),函数并没有执行,只是生成了一个generator对象,函数属于暂停状态,只有当执行.next()时,才会激活暂停状态,开始执行内部代码,直到遇到***个yield才会返回执行结果,并记住上下文,暂停,交出控制权。再次执行.next()时,找到第二个yield,再次记住上下文,暂停,交出控制权,依此重复。
如图所示,封装一个异步任务,定义一个generator对象,执行请求后交出控制权,通过promise判断是否要继续执行。在异步事件发生后,首先将控制权交给别人,让程序执行其它代码,当异步事件完成后,将控制权抢回来,继续执行其它操作。Generator需要一个自动执行器配合使用,实现正常思维下的异步处理,有了自动执行器,异步请求可以用同步的方式写异步代码,直接将请求全部写在一起。
通过进一步的演进,async和await函数应运而生。它们的个性特征如下:
Async与generator的写法类似,本质上是generator的语法糖。其内置执行器,具备更好的语义,更广的适用性。并且返回值是Promise。
网站栏目:还在找什么,JavaScript的异步编程解决方案全在这里了
文章链接:http://www.shufengxianlan.com/qtweb/news21/56371.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联