JavaScript

JS运行机制

2019-09-26  本文已影响0人  Aniugel

可以参考文章:
https://www.jianshu.com/p/7c85d160c183:必看
https://segmentfault.com/a/1190000012806637?utm_source=tag-newest:必看
http://www.ruanyifeng.com/blog/2014/10/event-loop.html
https://www.cnblogs.com/MasterYao/p/5563725.html

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

上面的打印顺序是什么? 1 3 2

设计知识点:JavaScript是单线程、任务队列(同步任务队列、异步任务队列)

console.log('A');
while(true){
}
console.log('B');

//输出结果
A(B执行不到)

console.log('A');
setTime(function(){
    console.log("B");
},0);
while(1){
}

//输出结果
A

//这题涉及异步队列被放入时候和执行时间
for(var i = 0;i<4;i++){
    setTimeout(function(){
        console.log(i);
    },1000);
}
//输出结果
4 4 4 4

for循环是同步任务,上面涉及异步队列执行的时候的概念,setTimeout是异步操作,同步执行完之前是被挂起的,并不执行。而且被没有被放入到异步队列中,直到设定的时间1000ms过后才被放入异步队列,此时i的值并不放入异步队列中去,i到4的时候,同步执行完,且过了设定时间,才执行事件循环中的异步队列。

如何理解JS的单线程: 一个时间之内只能干一件事。

什么是任务队列:分同步任务和异步任务

什么是Event Loop:就是事件循环

image.png

同步任务放入运行栈中,异步任务不会放入,过了设定时间放入异步任务队列中,同步任务执行完,异步任务队列中任务放入运行栈中,此时异步任务变成了运行栈中的同步任务来执行,栈中空了之后再去监听异步任务队列中有没有,有再去执行,如此循环,这个循环就是Event Loop(事件循环)。

关键点:
1.运行栈执行的是同步任务
2.什么时候去取异步任务队列中任务
3.什么时候去异步队列中放入任务

可以参考文章:
https://www.cnblogs.com/xiaohuochai/p/8527618.html
https://www.cnblogs.com/cangqinglang/p/8967268.html
https://www.cnblogs.com/yugege/p/9598265.html

什么时候执行异步任务?

1.setTimeout和setInterval

2.DOM事件(addEventListener)

3.ES6中的Promise

总结:

理解JS的单线程的概念

理解任务队列(同步任务队列、异步任务队列)

理解Event Loop

理解哪些语句会放入异步任务队列

理解语句放入异步队列的时机(过了设定时间)

题目
1、setTimeout、Promise、Async/Await 的区别
我觉得这题主要是考察这三者在事件循环中的区别,事件循环中分为宏任务队列和微任务队列。 其中settimeout的回调函数放到宏任务队列里,等到执行栈清空以后执行; promise.then里的回调函数会放到相应宏任务的微任务队列里,等宏任务里面的同步代码执行完再执行;async函数表示函数里面可能会有异步方法,await后面跟一个表达式,async方法执行时,遇到await会立即执行表达式,然后把表达式后面的代码放到微任务队列里,让出执行栈让同步代码先执行。
更加详细答案
2、Async/Await 如何通过同步的方式实现异步

async await 用于把异步请求变为同步请求的方式,第一个请求的返回值作为后面一个请求的参数,其中每一个参数都是一个promise对象
例如:这种情况工作中会经常遇到

(async () => {
    var a = await A();
    var b = await B(a);
    var c = await C(b);
    var d = await D(c);
})();
setTimeout 主要用户异步队列的形式,当然其中又分为宏观队列以及微观队列(Promise.then,process.nextTick等),比如隔1000ms执行一段逻辑代码(实际中不一定是1000ms后执行,需要考虑主任务的执行时间)

console.log(1);
setTimeout(() => {
    console.log(2)
}, 0)
setTimeout(() => {
    console.log(3)
}, 1000)
new Promise(resolve => {
    console.log(4)
    resolve()
}).then(() => {
    console.log(5)
})

3、异步输出

async function async1() {
    console.log('async1 start');
    await async2();
    console.log('async1 end');
}
async function async2() {
    console.log('async2');
}
console.log('script start');
setTimeout(function() {
    console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
    console.log('promise1');
    resolve();
}).then(function() {
    console.log('promise2');
});
console.log('script end');

详细答案

原文链接:https://blog.csdn.net/u014465934/article/details/86491034

上一篇下一篇

猜你喜欢

热点阅读