js异步等待完成后再进行下一步操作_JavaScript 异步详解

点击上方蓝字 关注我们!

d8f5dbe46c8a1e9ebbce20e738f013b9.png 7ba7cbdcc05424d6e440c0efd4e80a15.png 

相关概念

1 单线程&非阻塞I/O

JavaScript语言本身是单线程的。什么是单线程?可以理解为一次只能执行一个任务,所有的任务在执行开始前排成一个队列,等待顺序执行。

为什么是单线程? 如果JS是多线程的,一个线程在某个DOM节点上添加内容,同时另一个线程删除了这个节点,那浏览器以谁为准?所以为了避免复杂性,JavaScript从诞生起就是单线程的。

非阻塞I/O:I/O即Input/Output,非阻塞和阻塞的区别就在于在系统接收输入到输出期间,能不能接收其他的输入。

这里举一个例子:食堂排队打饭  /  餐厅点餐

食堂排队打饭: 我们排成一队打饭,阿姨为排到的人打饭( Input )时,是不会理会 后边的人想要什么的,直到给当前的人打完餐( Output )后,才会接受下一个人的需 求( 下一个Input ),这就是阻塞I/O餐厅点餐:我们进入餐厅后,服务员来为我们点餐( Input ),点餐结束后,服务员 将菜单传给后厨(扔进 任务队列 ----后边会详细介绍);接着服务员会为下一个人点餐 ( 下一个Input ),直到后厨做好,服务员根据餐桌位置把菜端上来( Output );在 此期间,服务员不断地点餐,送餐,后边的人不需要等待前边的人上完菜再点餐,这就是非阻塞I/O

因为非阻塞I/O的特性,也造就了JS能够高效率地执行代码,也能够承载高并发!

2 JS异步

异步(Asynchronous, async)是与同步(Synchronous, sync)相对的概念,我们来看下面这张图:

f9662b155fc7dc796f9de421a14af156.png

同步的流程中,所有任务需要等待上一个任务完成后才能开始执行; ----- 同步流程中,总执行时间是所有同步任务执行时间的总和。  而异步的任务则不需要等待前边的任务执行完成,就可以开始本次任务的执行,任务之间互 相不受干扰; ---- 异步流程中,总执行时间是耗时最长的异步任务所需时间。

对于JS来说,执行代码过程中有能够 的操作(比如声明、赋值、循环等,也称同步任务),还有一些的操作(比如定时器、网络请求、文件读写、事件监听等,也称异步任务),如果让他们像前边的任务一样老老实实地等待,这样对于单线程的JS来说执行效率就非常低,甚至会形成假死状态。

所以JS的宿主环境(浏览器、Node.js)会为这些耗时的操作单独开辟线程,比如网络请求线程、 定时器触发线程、浏览器事件触发线程、文件读写线程等,等这些任务被其他线程执行完成后,再通过回调的方式返回,这就是JS异步。

3 事件循环(Event Loop)

41300a1c0eea916918325f5992e7540a.png

JS主线程顺序读取代码,形成一个执行栈(execution context stack) ;

碰到耗时的操作,也就是需要异步执行的代码,主线程就根据异步类型分派给其他的异步线程去处理这些操作,当他们处理完成后,将结果扔给任务队列; 

当主线程把所有执行栈中的内容执行完成后,开始循环读取任务队列中,有完成的,就把这些异步的回调(callback)拉到主线程继续执行,如此反复,称为事件循环(Event Loop)

7ba7cbdcc05424d6e440c0efd4e80a15.png 

Java异步处理的历程

1 callback

最开始,我们基本都是通过函数传参callback回调函数来解决异步问题;

来看下面这段代码,假设我们请一位先生吃饭,就会有:

a41c406e2537cb6f7b2fcc7d4188fe4d.png

执行一下,控制台告诉我们结果是hungry。白吃了?其实并不是,这就相当于人刚说要开始吃,还没动筷子呢,就问人吃饱没,那不是很不礼貌么?

所以,得礼貌些,一定要在人吃完了再问。这里我们用callback回调函数的方式来问:

9e303297237977312e2a87e3d1bff6a0.png

再次执行,那指定是饱了 full ,因为是在人家吃完以后才问的。

我们再假设另外一种情况,如果这位先生饭量比较大,一碗饭根本不够吃,最终吃几碗能饱完

全看人心情,但是我们的钱包只够吃三碗饭的,实在吃不饱也没办法了:

11cc76f1299d221ef22638b0a4791b6a.png

bc592c0484b946b8afe6aa924a3badcc.png

先不管这个人吃没吃饱,我们看代码,三碗吃饭下来,一层套一层的回调函数+条件判断,代

码就显得很乱。这里逻辑还算是简单的,如果碰到复杂的,或者嵌套层数更多的情况,代码维

护起来就很困难,这就是经典的回调地狱( callback hell )问题。下面引入Promise来解决回调

地狱。

2Promise

Promise是 es6 中很重要的一个概念,也是我们最常用的异步解决方案。它是一个构造函数,

所以我们需要使用 new 关键字来创建一个Promise:

db835bbaef0256cebd81395a4021a96a.png

Promise译为承诺,表示承诺在未来有一个确切的答复;分别有以下三个状态,也称为状态机:

2de69a685a3277a33122e2be88587e6e.png

我们实例化一个Promise的时候,它就会进入pending状态,直到我们告诉它是成功 resolve() 还
是失败 reject() ,Promise才会改变状态:

0e2a185974b43ccbe4aafe56397c4d41.png

resolve 的内容会走到 then 回调中, reject 的内容会走到Promise后的第一个 catch (后边会

介绍)中,不管成功失败,都会走一个 finally :

1842354d43a4fce43de881081f4bc2bf.png

解决回调地狱,我们拟定三轮面试,三轮面试全部成功才算成功,否则就是失败:

cbd9d42012bb39f447ef678bdabcbc51.png

看得出来,所有的回调变成了链式调用,错误捕捉只需要一个 catch 拦截即可,这样大大提高了
代码的可读性和可维护性。

并发异步问题:假定一个场景,我们同时面试多家公司,只有都成功了才说明咱是大牛,否则就

是菜鸡;正常思维我们会开启一个计数器,面试通过就对计数器 +1 ,最后等待一定时间,再通

过判断计数器是否到达面试总数来决定自己是菜鸡还是大牛:

1f0075a73dde5fb483dea75404125ad1.png

43690cdc987f43b6be7c294ac1f7f224.png

这是我们知道每个 Promise 的结束时间,最终等待超过最长的即可,但是如果每轮面试的时

间都是未知的呢,怎么在最后做判断? 往下看

引入 Promise.all() 解决异步并发问题, Promise.all([]) 接受一个由 Promise 作为参数,当参

数中所有的 Promise 都成功后才会进入 Promise.all 的 then 回调中,并且会将三个 resolve

返回值作为数组返回给 Promise.all 的 then ,否则都会进入 catch 回调中:

e2ee7530e26a7eacffdb45b034f13fec.png

这样一来,不管每个面试多长时间,我们都能清晰地判断是否都完事了。

3async/await

async/await可以让我们用同步的思维去编写异步代码,被称为JS异步问题的终极解决方案

async 是修饰 function 的关键字, async function 其实是一个 Promise 的语法糖。观察下

面代码,我们执行 async function 返回的结果就是一个 Promise:

7e4675f3cbf175b588ed743983eaf8e5.png

await 是 async functon 中的一个关键字,用来阻止后边的代码立即执行,并且可以用同步的

方法获取到 Promise 的执行结果:

a68b4d03b61077b255b1537837e07c69.png

执行结果是 full ,但是看代码,并没有在回调中打印状态,而是直接在外部打印,并且能得到full

的状态,是因为 await 关键字起了作用,它的存在让异步编程回归到了同步。

那么用 async/await 的方式来写三轮面试的方式呢:

2ec4cd2361c82415dffab28ddba11f9a.png

01d3b864a2396525e905d1f790af5948.png

这段用同步的方式写出来的异步代码,我们拿来运行一下,就能够清晰地知道面试的过程,包括哪
一轮通过,到第几轮失败。注意:我们正常在外部是无法使用 try/catch 来捕捉 Promise 返回的 error ,但是使用async/await 就

可以轻松在外部捕捉到。

总结

1优先级

介绍了三种异步解决方案,那么我们在编码过程中应该如何选择呢?
推荐优先级: async/await > Promise > callback

Promise > callback

Promise 的链式调用能够让我们用线性思维去编写代码;

Promise 能够解决 callback 方式所产生的回调地狱问题;

async/await > Promise

async/await 允许我们用更容易理解的同步思维去编写代码; async/await 能够通过 try/catch 来捕捉 Promise 只能在 catch() 中捕获的错误; 通过 async/await 解决三轮面试的案例可以看出, async/await 在 接受中间值 方面表现得更加

优秀;

2兼容性

因为 Promise是语法,async/await是语法,所以兼容性方面还是有所欠缺,以下是它们在

can i use 网站中的表现:

65c24444b5fdd1914a5d98532478f9c2.png

but,这些问题在我们编码的时候可以通过构建工具来解决,如 babel 可以把我们的高版本JS

代码转换成浏览器能够通吃的兼容性代码。

结束语

异步的问题一直是JS三座大山(原型与原型链,作用域及闭包,异步和

单线程)之一,平常编码也经常碰到,希望本文能对大家有所帮助!

喜欢就点个在看再走吧 ea930d2435af2b1a51ff643a5a40dd4a.png
weixin_39629679
关注 关注
  • 13
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
js异步等待完成后再进行一步操作_Js Promise 与 异步操作
weixin_39526564的博客
12-03 8909
~为什么需要异步操作?比起同一时间只能干一件事,我们总是追求更高的效率,一边吃饭一遍写代码还能看直播。比如说当我们请求一个接口,后台响应的时间非常长,如果没有异步操作,程序只能傻等,进行不了下一步操作Js只有一个主线程执行,如果说我们能把复杂的需要时间处理的任务,交给一个模块去处理,不占用主线程,等它处理结束后,再得到响应就好了举个例子:我们要做吃饭、洗衣服、和看直播这三件事这三件事就会放入我们...
js异步等待完成后再进行一步操作_我理解的JavaScript异步编程
weixin_39924573的博客
11-21 2535
​引言最开始学习JS的时候就从知道了JS是单线程的,天生异步,适合IO密集型,不适合CPU密集型。但是,多数初学者从来没有认真思考过自己程序中的异步到底是怎么出现的,以及为什么会出现,也没有探索过处理异步的其他方法,甚至于一直在用callback来解决异步问题。为什么会出现异步浏览器内核的多线程一个浏览器至少三个常驻线程:JavaScript引擎线程,浏览器GUI渲染线程,浏览器事件触发线程。JS...
JS等待所有方法执行完成执行下一个方法,promise All
最新发布
JulyNight的博客
08-01 401
在工作中会遇到这样一个场景,前端需要拿到不同接口返回的结果在执行某个逻辑,当使用链式那样的方式去请求,等一个接口响应在请求下一个接口,这种方法就会导致请求时间特别长。这个时候就可以使用promise all,同时请求所有接口,然后使用Promise.all监听每个请求。promise相关用法,可以参考我的另外一篇文章http://t.csdnimg.cn/i3mUQ。
js等待异步执行完成后在执行
二月鸟
01-12 1032
参考文档1 参考文档2
关于 JS 中,实现在异步代码执行毕再执行后续代码
thirteen_king13的博客
05-11 2万+
因为 js 是单线程,所有的同步任务要等前一个任务执行毕,再执行下一个任务。 function fn1() { console.log("fn1") fn2() fn3() } function fn2() { console.time() for (let i = 0; i < 1000; i++) { console.log("fn2 repeat"); } console.timeEnd() } function fn3() { console.log("fn3") }
Js系列三:执行上下文
蜗牛不会跑
01-13 238
Js代码在运行的时候会进入一个特定的环境中,这个环境被称为执行上下文。在Js中运行环境主要包括以下三种情况 (1)全局环境既Js代码运行时首先进入的环境。 (2)函数环境:函数运行时会进入当前函数的环境执行代码。 (3)eval环境:此不推荐使用。 由此我们知道在Js程序执行过程中必然会出现多个执行环境(执行上下文)。Js引擎以函数调用栈的方式来处理,函数调用栈规定了Js代码的执行顺序。栈...
JS中的同步异步笔记
美人如玉,剑气如虹
10-28 290
JS中的同步异步 个人笔记,欢迎友好交流讨论。关于同步异步、微任务、宏任务、事件轮询、如何实现异步编程,内容较多,目前只学习了一小部分,继续gogogo!!! 单线程与多线程 单线程 JS是一门单线程的语言。单线程:如果在同一时间有多个任务,这些任务就需要排队执行,前一个任务执行,才会执行下一个任务。 为什么 JS 是单线程的语言? JS 是浏览器的脚本语言,主要用于实现和用户的交互。 前端主要使用 JS 实现对 DOM 的各种各样的操作,如果 JS 是多线程的语言, 那么一个线程 要对一个DOM节点
ES6 javascript异步操作实例详解
10-19
异步编程是指在程序执行过程中,允许一部分代码在等待某个事件发生(如I/O操作完成)时,继续执行其他代码,而不是让整个程序处于等待状态。在JavaScript中,由于其运行环境是单线程的,异步编程是避免界面无响应和...
详解JavaScript 异步编程
10-15
JavaScript异步编程是JavaScript开发中不可或缺的一个重要概念,它允许代码在不阻塞主线程的情况下执行耗时操作,从而提高应用程序的响应性和用户体验。本文将深入探讨异步编程的原理、应用场景以及常见的实现方式。...
Javascript异步编程详解
02-26
在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,"异步模式"甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降...
【前端】等待异步任务js执行毕再执行
我是Superman丶的博客
03-11 8498
【前端】等待异步任务js执行毕再执行 //页面加载毕后执行 $(function(){ console.info('---- 我是js代码 Start ----'); let promiseArr = []; let p = new Promise((resolve, reject) => { //当第三方api提供的是异步方法时 这里用setTimeout模拟
js等待异步执行完再执行_带我彻底弄懂JS执行机制
weixin_39811166的博客
12-03 3788
首先要知道JS是单线程,且分为同步任务和异步任务,同步任务就是即刻完成的任务,异步任务就是将来完成的任务。请思考://代码输出的结果是什么? 请再思考://代码输出的结果是什么? 所以我们知道js引擎第一步会将任务分成同步任务进入主线程,异步任务会进入Event table图解如下:第一步:console.log(1)进栈执行打印出1第二步:setTimeout是异步任务进入Event table...
js等待异步执行完再执行,js如何让代码同步执行
wenangou的博客
09-11 9917
。方法1内部用了var表示内部变量执行一次后会自动释放;方法2内的变量cc不能与方法1重名;示例代码如下测试可以varstr='';functioncfun(obj){str+=obj.value;}functionselall(){varcc=document.getElementsByTagName("input");for(vari=0;i谷歌人工智能写作项目:小发猫typescript兼容的浏览器版本,typescript web。你说的同步是一起执行还是和ajax的同步是单线程呢代码是从上往下执
JS语句中等某个方法执行完再执行后面逻辑
Ypromise-的博客
02-21 4956
在写script语句的时候,常遇到在代码逻辑中需要请求后台或别的运算方法执行拿到结果再继续执行代码的场景。
JS执行机制、宏任务和微任务详解
高先生的猫
07-27 1022
在了解之前先上一个常见的例子 console.log('script start'); setTimeout(function() { console.log('setTimeout'); }, 0); Promise.resolve().then(function() { console.log('promise1'); }).then(function() { console.log('promise2'); }); console.log('script end'); 以上代码的执
js处理异步问题】实现某段代码在指定代码执行完成后在执行
weixin_43253044的博客
01-08 495
js处理异步问题】实现某段代码在指定代码执行完成后在执行
js等待异步执行完再执行_JavaScript 中优雅使用顺序执行异步函数
热门推荐
weixin_39851261的博客
12-03 2万+
火于异步1995年,当时最流行的浏览器——网景中开始运行 JavaScript (最初称为 LiveScript)。 1996年,微软发布了 JScript 兼容 JavaScript。随着网景、微软竞争而不断的技术更新,在 2000年前后,JavaScript 相关的技术基础准备就绪。 随后到 2005 年前后,以 Google 为首开始重视使用 AJAX(即 Asynchronous Java...
imgkit 不执行js_浏览器中js异步执行(任务队列)
weixin_42511338的博客
12-03 212
相信大家都有听说js引擎是单线程执行,单线程执行也其实也就是指js执行过程中是从上到下一口气执行的,线程是操作系统中的最小执行单元,单线程如何实现异步呢?其实再js中的异步必须要配合第三方的API来完成,这个过程是js通知第三方的API去完成一项任务,在这个过程中js继续执行下面的任务,等到第三方的API完成后会将js回调函数放在浏览器维护的一个任务队列中,待js引擎处理当前的执行栈后,会去...
调用js_调用中国天气网天气不用js 最精准有效的方式
weixin_39782394的博客
12-26 276
网页调用天气是个麻烦的事情,需要判断当前地区的id,然后在知道地区的情况下 再去调用所在地区的天气, 一般需要js ajax获取 接口数据,而提供接口数据的网站 比如新浪、腾讯等等,接口地址又多变,总之就很麻烦。不过下面这个方法不依赖js,不依赖api,而且精准无误。主要得益于中国天气网的网页插件https://cj.weather.com.cn/代码片段天气加载中...#weather-view...
写文章

热门文章

  • js异步等待完成后再进行下一步操作_JavaScript 异步详解 12184
  • vue 将字符串转成date类型_JS和vue中日期格式的转换 9170
  • excel求方差和标准差的函数_Excel标准差_计算函数Stdev和StdevP的使用方法 7572
  • jwt 私钥_基于JWT的token弱密钥爆破 7477
  • 简述机器指令与微指令之间的关系_机器指令与微指令有什么联系和区别? 6869

最新文章

  • nt服务器虚拟,NT 下虚拟域名的实现-ASP教程,系统相关
  • 网页游戏一个服务器多少人,网页游戏开服数据报告
  • 华为服务器麒麟系统,通用服务器麒麟os
2021年144篇
2020年234篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳SEO优化公司驻马店网站优化软件东莞专业网站优化有哪些如何优化网站65金手指靠谱网站优化大师优化公司网站乙诵云速捷豪杰休宁seo网站优化济南网站优化企业兴化网站优化有用吗福田独立外贸网站优化服务哈尔滨网站优化公司共青城网站排名优化东莞网站优化哪家好卫辉优化网站排名兴宁百度seo网站优化潮州网站首页关键词优化工具雄安网站seo优化武汉旅游网站优化南充企业网站建设优化南宁什么叫网站优化呼和浩特网站优化就到胜优虎林网站优化湖南网站关键词排名优化靠谱网站快速优化外包仙桃网站优化推广公司福田哪家网站优化效果好企业官方网站优化哪家好网站推优化长沙关键词优化排名网站方山县网站seo优化排名哈尔滨优化网站公司哪家好歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化