js执行机制eventloop setTimeout async promise执行顺序

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、JavaScript是单线程语言

与用途有关,与用户进行互动,如操作DOM节点,在一个时间段内只能干一件事。
利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。

二、执行机制

分两类 同步任务和异步任务
操作分为:发出调用和得到结果两步。发出调用,立即得到结果是为同步。发出调用,但无法立即得到结果,需要额外的操作才能得到预期的结果是为异步。
事件机制

1.同步任务

所有任务都在主线程上执行,形成一个执行栈,执行完前一个,再能执行下个

2.异步任务

不进入主线程,主线程任务执行完通知"任务队列"(task queue)。系统把异步任务放到"任务队列"之中,然后继续执行后续的任务。

三、Event Loop

主线程内的任务执行完毕为空,会去task Queue读取对应的函数,先进先出原则进入主线程执行.这个过程不断重复称为事件循环
Event Loop
上图中,主线程运行的时候,产生堆(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函数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值