最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 浅谈JS异步编程

    正文概述 掘金(咸鱼蒻弱)   2021-03-11   430

    JS异步编程

    一.前导内容

    ​       在谈及具体的异步编程前,我们还需要知道何为同步编程,何为异步编程,这两者工作可是有着天差地别。

    1.1 何为同步?何为异步?

    ​       那让我来举个栗子吧:假如你需要去做两件事,分别是去煮饭,听一首歌,那么,煮完饭再去听歌的执行流程是同步编程流程。而先煮饭,在煮饭的过程中去听歌的执行流程则是异步编程流程。

    1.2 Javascript为什么是单线程

    ​       JS原本的任务就是负责浏览器和用户之间的交互功能,因为JS要操作DOM,所以必须是单线程的,如果你是JS的话,请你想想如果有多个线程同时操作同一个DOM,想必你会抓狂的吧。正因为如此,所以排队等待时间未免太过漫长,所以才有了我们现在口中的JS异步编程的方案。

    二.异步编程的核心与方法

    2.1 如何实现异步编程?异步编程的核心是什么?

    ​       实现异步编程的方案有很多,例如:回调函数、promise对象,事件监听、发布/订阅等等方案,但万变不离其中,所有异步编程的核心就是回调函数。下面我来举例具体说明一下什么是回调函数:

    ​       假如在煮好饭后要把听歌的耳机放到耳机架上,那么就要把这个事告诉你对象,那异步流程就变成了——你先煮饭,然后告诉你对象等你听完歌需要把耳机放到耳机架上,然后你再去听歌。在这个流程中,把耳机放回耳机架是回调函数,也就是在任务完成后你需要执行的操作,你就是异步操作的调用者,你对象就是异步操作的执行者,总结起来就是——由调用者定义,交给执行者执行的函数,就是回调函数。

    2.2 回调地狱问题如何解决?

    ​       说起回调地狱,想必很多小伙伴并不陌生,这个问题也困扰着当时初学JS的我,想当初可是被这个问题折磨了一段时间。接下来就由我给大家说说回调地狱,具体来说回调地狱就是,当你执行DOM事件时,比如在页面上点击链接、回车等操作,浏览器都会悄悄地向服务端发送很多个http请求,携带后台可识别的参数,等待服务器返回数据,这个过程是异步回调的,当很多功能环环依赖时,代码会一层一层的嵌套起来,看起来十分庞大且恶心.

    ​     正是因为回调地狱不利于阅读,同时也不利于维护,所以前辈们为了解决这一问题,在很多方面做出了努力,这个时候我要跟大家分享一个JS异步编程的一个核心要点——promise,下面请用心分析我所说的内容:

    (一)何为promise?

    ​      promise是一个构造函数,返回一个promise对象。一个promise指的是一个可能会在未来的某个时间点产生一个单一值的对象。我这里有一个很好的说法可以描述一下promise的机制:

    ​       好比你去汉堡店买汉堡包吃,你已经付好了钱,但是却被告知汉堡包已经售空,而店员为了解决你的问题,给了你一张汉堡兑换券,这张券不会过期,她让你明天再来拿券兑换汉堡包。虽然你的券可以换到汉堡包,但是你也不能确定你明天来时是否有汉堡可以兑换,但可以确定的是,你一定能在未来的某一天,兑换到这个汉堡包。

    (二)promise自身的三种状态 (状态改变后就不会再变化)

    ​        (1)fulfilled:成功

    ​        (2)rejected:失败

    ​        (3)pending:等待

    ​   (三)promise的用法

    ​        promise给定了一些原型方法来进行状态处理

    1.promise.prototype.then :

    ​        promise对象通过内部resolve函数完成状态的pending ->fulfilled。之后promise将保留这个状态。可以通过then去处理状态。例:pm.then( (val) =>{console.log(val); } )

    处理rejected状态,then方法可接收两个函数

    
    new Promise(function(resolve,reject){
    
    	setTimeout(() =>{
    	
    ​    	reject(new Error('err'))
    
    	},2000).then(null,(error) =>{
    
    ​    		console.log(error);
      	})
    })
    

    2.promise.prototype.catch:

           用来做错误统一处理,这样的链式调用中我们只需要用then来处理fulfilled状态,在链的末尾加上catch来统一处理错误。

    new Promise((resolve,reject) =>{
    
      setTimeout(() =>{
    
    ​    resolve = 100;
    
      },2000).then(result =>{
    
    ​    return result * num;
    
    ​    return result / 2;}).catch(err =>{
    
    ​      console.log(err);
    
    ​    })
    
    })
    

    3.promise.prototype.finally():

           这个API放在结尾,这时候你们肯定会好奇这是为什么呢?因为它不管前面的promise变为什么,它都会执行里面的回调函数。

    new Promise((resolve,reject) =>{
    
      setTimeout(() =>{
    
    ​    resolve = 100;
    
      },2000).then(result =>{
    
    ​    return result * num;
    
    ​    return result / 2;}).catch(err =>{
    
    ​      console.log(err);
    
    ​      console.log('complete')
    
    ​    })
    
    })
    

    4.promise.all

    Promise.all([A,B]).then(resA,resB) =>{
    
      //do something
    
    }
    

    5.promise链式调用

           promise对象的then方法会返回一个权限的promise对象

    后面的then方法就是为了上一个then返回的promise注册回调

    前面的then方法中回调函数的返回值会作为后面then方法回调的参数

    如果回调返回的是Promise,后面的then方法的回调会等待它的结束

    2.3 EventlLoop的执行顺序

    ​        EventLoop被称作事件轮询,也称为事件循环,而EventLoop的作用只有一个:监听调用栈和消息队列,一旦调用栈清空,EventLoop就会从消息队列中取出第一个回调函数,压入栈中执行它。

           而就我个人的观点来看,我是这么理解它的:代码从上到下执行,如果遇到微任务就放到微任务队列中,遇到宏任务就放到宏任务队列中,所有代码被执行栈执行完后,先去微任务列表中执行任务,待解决所有微任务后,再去宏任务队列解决所有宏任务。

    注意:
    1.每当执行完当前宏任务时,都会返回微任务列表看是否有微任务需要执行,若存在微任务则先执行微任务,若没有微任务存在,则执行剩下的宏任务。

    2.微任务不需要到队列队尾进行排队处理。

           今天的分享就到这啦,这里是一条从艺术行业初入前端的小咸鱼,欢迎大家提出宝贵的建议,并一起讨论前端的技术知识,希望大家都能在不久的将来成为一名前端老鸟。


    起源地下载网 » 浅谈JS异步编程

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元