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.onbeforeunload的取消事件
Mar 06 Javascript
jquery实现的下拉和收缩效果示例
Aug 21 Javascript
jQuery中:not选择器用法实例
Dec 30 Javascript
javascript获取四位数字或者字母的随机数
Jan 09 Javascript
jQuery实现平滑滚动页面到指定锚点链接的方法
Jul 15 Javascript
jQuery实现点击后标记当前菜单位置(背景高亮菜单)效果
Aug 22 Javascript
jQuery实现响应鼠标背景变化的动态菜单效果代码
Aug 27 Javascript
详解JavaScript中的构造器Constructor模式
Jan 14 Javascript
jquery 全选、全不选、反选效果的实现代码【推荐】
May 05 Javascript
JS创建Tag标签的方法详解
Jun 09 Javascript
详解webpack的proxyTable无效的解决方案
Jun 15 Javascript
详解vue的双向绑定原理及实现
May 05 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中通过trigger_error触发PHP错误示例
2015/06/23 PHP
php生成固定长度纯数字编码的方法
2015/07/09 PHP
Laravel构建即时应用的一种实现方法详解
2017/08/31 PHP
window.onload 加载完毕的问题及解决方案(上)
2009/07/09 Javascript
js验证整数加保留小数点的简单实例
2013/12/02 Javascript
JS按回车键实现登录的方法
2014/08/25 Javascript
在JavaScript中操作时间之getYear()方法的使用教程
2015/06/11 Javascript
基于bootstrap3和jquery的分页插件
2015/07/31 Javascript
基于dropdown.js实现的两款美观大气的二级导航菜单
2015/09/02 Javascript
JavaScript驾驭网页-获取网页元素
2016/03/24 Javascript
浅谈Vuejs Prop基本用法
2017/08/17 Javascript
vue+node+webpack环境搭建教程
2017/11/05 Javascript
javaScript字符串工具类StringUtils详解
2017/12/08 Javascript
React 使用browserHistory项目访问404问题解决
2018/06/01 Javascript
Vue利用Blob下载原生二进制数组文件
2019/09/25 Javascript
ES6常用小技巧总结【去重、交换、合并、反转、迭代、计算等】
2019/12/21 Javascript
[00:57]辉夜杯战队访谈宣传片—VG
2015/12/25 DOTA
python学习笔记:字典的使用示例详解
2014/06/13 Python
低版本中Python除法运算小技巧
2015/04/05 Python
Python2.x版本中maketrans()方法的使用介绍
2015/05/19 Python
Python中特殊函数集锦
2015/07/27 Python
Python实现一个Git日志统计分析的小工具
2017/12/14 Python
利用Python代码实现数据可视化的5种方法详解
2018/03/25 Python
Python定义函数功能与用法实例详解
2019/04/08 Python
python粘包问题及socket套接字编程详解
2019/06/29 Python
Python分割训练集和测试集的方法示例
2019/09/19 Python
python3爬取torrent种子链接实例
2020/01/16 Python
python GUI库图形界面开发之PyQt5日期时间控件QDateTimeEdit详细使用方法与实例
2020/02/27 Python
使用python编写一个语音朗读闹钟功能的示例代码
2020/07/14 Python
详解Java中一维、二维数组在内存中的结构
2021/02/11 Python
浅谈HTML5 FileReader分布读取文件以及其方法简介
2017/11/09 HTML / CSS
HTML5 video循环播放多个视频的方法步骤
2020/08/06 HTML / CSS
Nike德国官网:Nike.com (DE)
2018/11/13 全球购物
Mountain Warehouse波兰官方网站:英国户外品牌
2019/08/29 全球购物
清洁工表扬信
2014/01/08 职场文书
物流专业求职计划书
2014/01/10 职场文书