提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
一、JavaScript是单线程语言
与用途有关,与用户进行互动,如操作DOM节点,在一个时间段内只能干一件事。
利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。
二、执行机制
分两类 同步任务和异步任务
操作分为:发出调用和得到结果两步。发出调用,立即得到结果是为同步。发出调用,但无法立即得到结果,需要额外的操作才能得到预期的结果是为异步。
1.同步任务
所有任务都在主线程上执行,形成一个执行栈,执行完前一个,再能执行下个
2.异步任务
不进入主线程,主线程任务执行完通知"任务队列"(task queue)。系统把异步任务放到"任务队列"之中,然后继续执行后续的任务。
三、Event Loop
主线程内的任务执行完毕为空,会去task Queue读取对应的函数,先进先出原则进入主线程执行.这个过程不断重复称为事件循环
上图中,主线程运行的时候,产生堆(heap)和栈(stack),栈中的代码调用各种外部API,它们在"任务队列"中加入各种事件(click,load,done)。只要栈中的代码执行完毕,主线程就会去读取"任务队列",依次执行那些事件所对应的回调函数。
执行栈中的代码,总是在读取"任务队列"之前执行
三、定时器
任务队列可放置异步任务,也可放置定时事件,多长时间事件后在执行
主要有 setTimeout()和setInterval()这两个函数来完成
区别不大 前者执行一次 后者自动重复执行多次
setTimeout()只是将事件插入了"任务队列",必须等到当前代码(执行栈)执行完,主线程才会去执行它指定的回调函数。没有办法保证,回调函数一定会在setTimeout()指定的时间执行。
HTML5标准规定了setTimeout()的第二个参数的最小值(最短间隔),不得低于4毫秒,如果低于这个值,就会自动增加。在此之前,老版本的浏览器都将最短间隔设为10毫秒。
另外,对于那些DOM的变动(尤其是涉及页面重新渲染的部分),通常不会立即执行,而是每16毫秒执行一次。这时使用requestAnimationFrame()的效果要好于setTimeout()。
四、宏任务和微任务
宏任务:也叫macrotask,在JavaScript中,一些异步任务会进入macrotask队列中,等待被调用,常见的异步任务有:setTimeout,setInterval,dom事件回调函数,Ajax回调函数等。
微任务:也叫microtask,常见的有Promise,process.nextTick 。
js代码
执行顺序是:主线程代码 (同步代码)> 微任务 > 宏任务
五、setTimeout async promise执行顺序总结
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');
setTimeout函数时,将其回调函数加入异步队列中宏任务
promise对象里面的代码属于同步代码
调用async函数的时候会返回一个Promise对象。Promise对象是立即执行的
await 将promise对象变成同步同步代码
await async2();//,输出async2后,await会让出当前线程,将后面的代码加到任务队列中,然后继续执行执行函数后面的同步代码
任务队列执行 按照顺序先进先出
队列任务优先级:promise.Tick()>promise的回调>async>setTimeout>setImmediate,
执行结果不同浏览器 promise2和async1 end可能不相同
。截图取自谷歌
总结
以上博客,都是因为今天面试官问我
1 promise 和settimeout 哪个先执行 答 :promise
2 怎么样让 settimeout在promise前面执行
目前只能想让在settimeout回调函数中执行promise函数。