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 相关文章推荐
精解window.setTimeout()&window.setInterval()使用方式与参数传递问题!
Nov 23 Javascript
JQueryEasyUI datagrid框架的基本使用
Apr 08 Javascript
js数组方法扩展实现数组统计函数
Apr 09 Javascript
jquery实现的网页自动播放声音
Apr 30 Javascript
JS输入用户名自动显示邮箱后缀列表的方法
Jan 27 Javascript
jQuery使用slideUp方法实现控制元素缓慢收起
Mar 27 Javascript
原生JavaScript制作微博发布面板效果
Mar 11 Javascript
微信小程序之仿微信漂流瓶实例
Dec 09 Javascript
微信小程序  checkbox组件详解及简单实例
Jan 10 Javascript
Vue.js之slot深度复制详解
Mar 10 Javascript
VUE多层路由嵌套实现代码
May 15 Javascript
JavaScript find()方法及返回数据实例
Apr 30 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
Discuz 6.0+ 批量注册用户名
2009/09/13 PHP
PHP开发的一些注意点总结
2010/10/12 PHP
把1316这个数表示成两个数的和,其中一个为13的倍数,另一个是11的倍数,求这两个数。
2011/06/24 PHP
php一个解析字符串排列数组的方法
2015/05/12 PHP
基于Laravel实现的用户动态模块开发
2017/09/21 PHP
php递归函数怎么用才有效
2018/02/24 PHP
各情景下元素宽高的获取实现代码
2011/09/13 Javascript
JavaScript的instanceof运算符学习教程
2016/06/08 Javascript
JQuery Ajax WebService传递参数的简单实例
2016/11/02 Javascript
Vue计算属性的学习笔记
2017/03/22 Javascript
vue2实现移动端上传、预览、压缩图片解决拍照旋转问题
2017/04/13 Javascript
JS获取浏览器地址栏的多个参数值的任意值实例代码
2018/07/24 Javascript
详解vue中localStorage的使用方法
2018/11/22 Javascript
angular2 NgModel模块的具体使用方法
2019/04/10 Javascript
Python numpy生成矩阵、串联矩阵代码分享
2017/12/04 Python
python实现pdf转换成word/txt纯文本文件
2018/06/07 Python
Python3实现的回文数判断及罗马数字转整数算法示例
2019/03/27 Python
python 检查数据中是否有缺失值,删除缺失值的方式
2019/12/02 Python
Python 解决OPEN读文件报错 ,路径以及r的问题
2019/12/19 Python
Python3通过chmod修改目录或文件权限的方法示例
2020/06/08 Python
举例详解HTML5中使用JSON格式提交表单
2015/06/16 HTML / CSS
卡塔尔航空官方网站:Qatar Airways
2017/02/08 全球购物
英国领先的高级美容和在线皮肤诊所:Face the Future
2020/06/17 全球购物
CSMA/CD介质访问控制协议
2015/11/17 面试题
重写子类方法时,抛出异常的书写注意事项
2015/10/17 面试题
文职个人求职信范文
2013/09/23 职场文书
总经理岗位职责范本
2014/02/02 职场文书
产品质量承诺书
2014/03/27 职场文书
2014年“四风”问题个人整改措施
2014/09/17 职场文书
2014年财务工作总结与计划
2014/12/08 职场文书
求职自我评价怎么写
2015/03/09 职场文书
仓库统计员岗位职责
2015/04/14 职场文书
小学语文继续教育研修日志
2015/11/13 职场文书
PyQt5爬取12306车票信息程序的实现
2021/05/14 Python
详解apache编译安装httpd-2.4.54及三种风格的init程序特点和区别
2022/07/15 Servers
win10电脑右下角输入法图标不见了?Win10右下角不显示输入法的解决方法
2022/07/23 数码科技