JS面试—异步和单线程

目录

一、题目

1、同步和异步的区别是什么?分别举一个同步和异步的例子

2、一个关于setTimeout的笔试题

3、前端使用异步的场景有哪些

4、异步和单线程的关系

二、知识点

2.1 什么是异步(对比同步)

2.2 何时使用异步?

2.3 前端使用异步的场景

2.4 异步和单线程


一、题目

1、同步和异步的区别是什么?分别举一个同步和异步的例子

同步会阻塞代码执行,而异步不会(alert是典型的同步,setTimeout是典型的异步)。

 比如说,在同步中遇见alert,如果你不点击弹出框的确定按钮,代码就卡在了这个地方,如果你永远不点击,它就永远不会向下执行,但是异步就不一样,比如setTimeout,它会把异步代码先拿出来,另存起来,然后继续往下执行其他代码,等代码都执行完成之后,再看看内存里是否有另存起来的代码,如果有,再按照要求执行这部分代码。

2、一个关于setTimeout的笔试题

console.log(1)
setTimeout(function (){
    console.log(2)
},0);
console.log(3);
setTimeout(function (){
    console.log(4)
},1000)
console.log(5)

输出结果 13524 

3、前端使用异步的场景有哪些

  • 定时任务:setTimeout,setInverval
  • 网络请求:ajax请求,动态<img>加载
  • 事件绑定

4、异步和单线程的关系

javascript之所以是异步,是因为它是单线程执行的,所以它必须有异步

二、知识点

2.1 什么是异步(对比同步)

js的运行机制就是单线程异步。js单线程的概念就是一个时间内只能执行一个东西。

  • 同步任务的概念。

同步就是发出一个功能调用的时候,在没有得到结果之前,该调用就不返回或者不继续执行后续操作。

同步的典型是alert;刷新页面也是个同步的例子,当我们刷新页面的时候页面会有一个空档期,他是白颜色的,体验不好。同步的例子如下:

console.log(100);
alert(200);       //弹出框如果不点击确定就不会继续执行后续操作
console.log(300);

//这个就是同步的例子,如果第二行alert弹出框不点击确定,下面代码就没法执行。
//所以说同步会阻塞下面代码执行,异步不会阻塞。

同步异步最大的区别有没有阻塞程序进行

  • 异步任务的概念。

异步与同步是相对的,当一个异步过程调用发出后,调用者在没有得到结果之前,就可以继续执行后续操作。当这个调用完成后,一般是通过状态、通知和回调来通知调用者。对于异步的调用,调用的返回并不受调用者控制。

console.log(100);
setTimeout(function(){
    console.log(200)
},1000);
console.log(300);

输出结果依次为100,300,200 

console.log("A");
setTimeout(function(){
console.log("B");
},100)
while(true){

}

 结果是:A

因为setTimeout是异步任务,同步任务while一直在运行,所以不会运行异步任务,所以结果一直是A。

var i;
for(i=0;i<4;i++){
setTimeout(function(){
console.log(i);
},1000)      //0跟1000输出的结果都一样
}

 结果是:输出四次4

因为主要考虑队列插入的时间,for循环是同步任务,执行0的时候符合小于4,运行setTimeout,它是个异步任务,此时i是0,setTimeout不是直接放到异步队列里,而是先挂起,等等待的时间到了(比如1000毫秒),才放到异步队列里,for循环运行的速度特别快。所以最后setTimeout执行的时候i已经变成4了,输出的就是四个4。

如果是0的时候它也不是0,以前浏览器最小的是10毫秒,现在浏览器规定最小是4毫秒,for循环运行特别快,所以4毫秒之内早都运行完了,所以也是输出的四个4。

注意:要理解哪些语句会放入异步任务队列中。放入异步任务队列的时机。

关于Event Loop事件循环的概念

就是有一个运行栈执行同步任务的,当浏览器遇到一个setTimeout,它会认为是个异步任务,不会放到运行栈里面,浏览器会有一个特定模块,来拿走这个setTimeout,当到了setTimeout时间,会把这个异步任务放到异步队列中,同步执行完了,运行栈中没有要执行的任务了,它就去读异步队列,如果发现异步队列中有,它就把异步队列中的任务放到运行栈中执行。等执行完,运行栈中又空了,它会继续看异步队列中有没有异步任务,如果有,还放到运行栈中执行,一直下去。

2.2 何时使用异步?

  1. 在可能发生等待的情况
  2. 等待过程中不能行alert一样阻塞程序运行
  3. 因此,所有的“等待情况”都需要异步

一句话总结就是需要等待但是又不能阻塞程序的时候需要使用异步

2.3 前端使用异步的场景

异步的设计主要是因为javascript是一个单线程的语言,单线程只允许同时做一件事情,如果同时需要做多个,那其他的需要去旁边排队去

  • 定时任务:setTimeout,setInverval
  • 网络请求:ajax请求,动态<img>加载
  • 事件绑定  比如一个点击事件,我不知道它什么时候点,但是在它点击之前,我该干什么还是干什么。用addEventListener注册一个类型的事件的时候,浏览器会有一个单独的模块去接收这个东西,当事件被触发的时候,浏览器的某个模块,会把相应的函数扔到异步队列中,如果现在执行栈中是空的,就会直接执行这个函数。
  • ES6中的Promise

img图片的动态加载异步例子:

console.log("start");
var img=document.createElement_x_x_x_x("img");
img.onload=function(){
console.log("loaded");
}
img.src="/xxx.png";
console.log("end");
结果先输出start 再输出end最后输出loaded

事件绑定的例子:

console.log("start");
var btn1=document.getElementById("btn1");
btn1.addEventListener('click',function(){
console.log("clicked");
})
console.log("end");
结果先输出start再输出end点击按钮之后输出clicked,点击多少次输出多少次clicded

2.4 异步和单线程

javascript之所以是异步,是因为它是单线程执行的,所以它必须有异步

js是一直是单线程的,浏览器才是实现异步的那个家伙。

下面的例子,讲述异步和单线程的执行步骤:

console.log(100);
setTimeout(function(){
    console.log(200)
});
console.log(300);

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值