js面试题之异步问题的深入理解


Posted in Javascript onSeptember 20, 2020

js中的宏任务与微任务

在面试过程中,基本面试官都会问你一些promise的问题,promise是es6的新内容,主要是用来优化异步的问题。笔试中经常会让你写一些promise和setTimeout的执行结果,这你就必须知道宏任务和微任务的概念了!

为什么要使用promise

如果你经历过以前的jquery开发项目,你会遇到以下问题:回调地狱

$.ajax({
	...
	success: function() {
		...
		$.ajax({
			...
			success: function() {
				
			}
		})
		...
	}
})

原因分析:

ajax请求嵌套,原因是我第二个请求依赖的参数在第一个请求的结果中,所以就得这么一直嵌套下去,ajax是异步的,不能再外面拿到里面的结果。这种代码导致的问题就是调试困难,耦合性非常高,后期改动一个地方就头疼!维护非常困难,代码可读性差。

于是乎就引入了promise对ajax进行了优化,axios就是基于promise的一个请求封装库,他们底层都是基于js原生的XMLHTTPREQUEST.

promise().then().catch()链式调用,多个请求可以promise().then().then()。

何为宏任务,何为微任务?

思考这个问题时你必须知道javascript是一种单线程的脚本语言,也就是它的代码正常只能从上往下依次执行,一次只能做一件事,异步是通过回调函数来实现的。为何不把js设计成多线程的语言呢?语言的用途决定了它的特性,js最初是用来做表单验证以及正则判断的,和操作DOM元素的。如果js有多个线程,一个执行DOM元素修改,另一个执行删除,那浏览器直接懵逼了,我到底该干啥???所以语言的用途决定了他的特性,但是浏览器是多线程的,除了主线程还有其他线程。

当js主程序执行时,先运行主程序上的同步代码,遇到setTimeout或setInterval就把它放入宏队列中,遇到promise的回调就把它放到微队列中,程序执行先执行主程序代码,再执行nextTick代码,然后微任务,最后宏任务,任务队列中的依次排队执行,async和await是配套使用的,await后面接一个promise对象,来看看下面这段代码:

setTimeout(function(){console.log(1)},0); // 进入宏任务队列,最后执行宏任务
 new Promise(function(resolve,reject){
   console.log(2); //这句代码在promise构造器,同步执行
   resolve(); // 执行了resolve再把任务放入微队列
 }).then(function(){console.log(3)
 }).then(function(){console.log(4)});
 process.nextTick(function(){console.log(5)});
 console.log(6); // 主程序代码
 // 输出2,6,5,3,4,1
 
// 下面这个进阶代码
setTimeout(function(){console.log(1)},0); // 进入宏任务排序为1
new Promise(function(resolve,reject){
   console.log(2);
   // promise中执行完resolve()才会执行then(),而这里的resolve在宏任务里,执行完主程序代码后,还得先执行先进入宏队列中的程序
   setTimeout(function(){resolve()},0) // 进入宏任务排序为2
 }).then(function(){console.log(3)
 }).then(function(){console.log(4)});
 process.nextTick(function(){console.log(5)});
 console.log(6);
 // 输出的是 2 6 5 1 3 4

再看async and await中的执行顺序

代码如下(示例):

async function async1() {
  console.log(1); 
  await async2();
  console.log(2); //这里要等await执行成功才会执行,进入微任务,排序1
}
async function async2() {
  console.log(3);
}
console.log(4); //主程序代码
setTimeout(function() {
  console.log(5);
}, 0) //进入宏任务,最后执行
async1();
new Promise(function(resolve) {
  console.log(6); // 这句同步执行
  resolve(); 
}).then(function() {
  console.log(7); //进入微任务,排序2
});
console.log(8); // 主程序代码
// 输出的是 4,1,3,6,8,2,7,5

总结

js是单线程语言,它的用途决定了他的特性,异步操作通过事件循环机制,先执行同步代码,然后微任务,最后宏任务,两个任务队列里的任务排队依次执行。await后面的代码必须等待promise返回结果再执行下面代码,await和async是generator函数的语法糖。

到此这篇关于js面试题之异步问题的文章就介绍到这了,更多相关js面试题之异步内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
sina的lightbox效果。
Jan 09 Javascript
基于jquery完美拖拽,可返回拖动轨迹
Mar 29 Javascript
在js(jquery)中获得文本框焦点和失去焦点的方法
Dec 04 Javascript
jquery获取对象的方法足以应付常见的各种类型的对象
May 14 Javascript
JavaScript中的变量定义与储存介绍
Dec 31 Javascript
聊一聊JavaScript作用域和作用域链
May 03 Javascript
Angularjs中ng-repeat-start与ng-repeat-end的用法实例介绍
Dec 31 Javascript
微信小程序开发之相册选择和拍照详解及实例代码
Feb 22 Javascript
vue使用技巧及vue项目中遇到的问题
Jun 04 Javascript
Javascript中绑定click事件的四种方式介绍
Oct 26 Javascript
Angular+ionic实现折叠展开效果的示例代码
Jul 29 Javascript
Element-ui upload上传文件限制的解决方法
Jan 22 Javascript
js实现简单的点名器随机色实例代码
Sep 20 #Javascript
前端vue+elementUI如何实现记住密码功能
Sep 20 #Javascript
Vue+element+cookie记住密码功能的简单实现方法
Sep 20 #Javascript
解决vue项目运行提示Warnings while compiling.警告的问题
Sep 18 #Javascript
vue-cli3 热更新配置操作
Sep 18 #Javascript
vue-cli 关闭热更新操作
Sep 18 #Javascript
Node.JS如何实现JWT原理
Sep 18 #Javascript
You might like
php中计算程序运行时间的类代码
2012/11/03 PHP
php获取远程文件内容的函数
2015/11/02 PHP
PHP递归删除多维数组中的某个值
2017/04/17 PHP
用jQuery实现检测浏览器及版本的脚本代码
2008/01/22 Javascript
JavaScript 学习点滴记录
2009/04/24 Javascript
clientX,pageX,offsetX,x,layerX,screenX,offsetLeft区别分析
2010/03/12 Javascript
初窥JQuery-Jquery简介 入门了解篇
2010/11/25 Javascript
JavaScript实现向右伸出的多级网页菜单效果
2015/08/25 Javascript
JS组件系列之Bootstrap table表格组件神器【终结篇】
2016/05/10 Javascript
jquery获取复选框checkbox的值实现方法
2016/05/30 Javascript
Bootstrap Scrollspy源码学习
2017/03/02 Javascript
解决jQuery ajax动态新增节点无法触发点击事件的问题
2017/05/24 jQuery
Vue.js中extend选项和delimiters选项的比较
2017/07/17 Javascript
原生js实现仿window10系统日历效果的实例
2017/10/31 Javascript
微信小程序使用wxParse解析html的方法示例
2019/01/17 Javascript
jQuery中实现text()的方法
2019/04/04 jQuery
微信小程序开发实现的选项卡(窗口顶部/底部TabBar)页面切换功能图文详解
2019/05/14 Javascript
SpringBoot+Vue开发之Login校验规则、实现登录和重置事件
2020/10/19 Javascript
python使用urllib模块和pyquery实现阿里巴巴排名查询
2014/01/16 Python
python监控网站运行异常并发送邮件的方法
2015/03/13 Python
python通过floor函数舍弃小数位的方法
2015/03/17 Python
深入讲解Python中面向对象编程的相关知识
2015/05/25 Python
Python的Flask框架中集成CKeditor富文本编辑器的教程
2016/06/13 Python
python实现关键词提取的示例讲解
2018/04/28 Python
Python人脸识别第三方库face_recognition接口说明文档
2019/05/03 Python
在Python中os.fork()产生子进程的例子
2019/08/08 Python
Python批量将图片灰度化的实现代码
2020/04/11 Python
基于python实现可视化生成二维码工具
2020/07/08 Python
canvas需要在标签里直接定义宽高
2014/12/17 HTML / CSS
管理心得体会
2013/12/28 职场文书
上课说话检讨书大全
2014/01/22 职场文书
廉洁自律承诺书
2014/03/27 职场文书
个人整改措施落实情况汇报
2014/10/29 职场文书
2016年教师党员承诺书范文
2016/03/24 职场文书
详解Redis实现限流的三种方式
2021/04/27 Redis
mysql主从复制的实现步骤
2021/10/24 MySQL