资讯专栏INFORMATION COLUMN

一道setTimeout async promise执行顺序的笔试题引发的思考

soasme / 1533人阅读

摘要:如果你要问他和谁当进去的快,要从下面两个方面考虑结束时。至于什么,查了很多的资料,了解到一个浏览器环境只能有一个事件循环,而一个事件循环可以有多个任务队列。

====据说这是今日头条去年的一道笔试题,主要考察的是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");
 

首先,我们先来了解几个概念:

JS众所周知是单线程语言,Javascript引擎同一时刻只能执行一个代码块,使用Event Loop作为它的异步执行机制

那么Event Loop是如何实现异步呢,个人浅显的理解如下:

同步代码按照上下文的顺序放进主进程中去执行

异步函数放进异步队列中,等待执行,在异步队列执行的顺序按照先进先出的原则

等主进程中的同步函数执行完毕后,轮询去执行异步队列中的异步函数

⚠️注意: setTimeOut并不是直接的把你的回掉函数放进上述的异步队列中去,而是在定时器的时间到了之后,把回掉函数放到执行异步队列中去。如果此时这个队列已经有很多任务了,那就排在他们的后面。这也就解释了为什么setTimeOut为什么不能精准的执行的问题了。setTimeOut执行需要满足两个条件:

1. 主进程必须是空闲的状态,如果到时间了,主进程不空闲也不会执行你的回掉函数 
2. 这个回掉函数需要等到插入异步队列时前面的异步函数都执行完了,才会执行

理解了Eventloop异步实现的方式,再来补充一下promise、async/await

首先,new Promise是同步的任务,会被放到主进程中去立即执行。而.then()函数是异步任务会放到异步队列中去,那什么时候放到异步队列中去呢?当你的promise状态结束的时候,就会立即放进异步队列中去了。如果你要问他和setTimeOut谁当进去的快,要从下面两个方面考虑:

1. promise结束时。.then内函数插入异步队列的时间与setTimeOut的回掉函数插入队列的时间,谁的早,谁的就最快
2. **如果promise是同步的而setTimeOut时间是0,那么是promise先执行**。至于什么,查了很多的资料,了解到:一个浏览器环境只能有一个事件循环,而一个事件循环可以有多个任务队列。settimeout所在的队列与promise.then()的队列不同,面对此种情况,v8实现的时候会先从promise.then()的队列取任务,但是并没有很理解,如果有大佬愿意指点迷津,请留言告知           
               
                                           
                       
                 

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99720.html

相关文章

  • 试题之Event Loop终极篇

    摘要:下面开始分析开头的代码第一轮事件循环流程整体作为第一个宏任务进入主线程,遇到,输出遇到函数声明,声明暂时不用管遇到,其回调函数被分发到微任务中。我们记为遇到,其回调函数被分发到宏任务中。 先上一道常见的笔试题 console.log(1); async function async1() { console.log(2); await async2(); con...

    niceforbear 评论0 收藏0
  • JS异步笔试题

    摘要:分析题目先执行微任务后执行宏任务因此结果为按照这个思路做以下题目做出如下更改运行结果为更改如下更改如下运行结果为运行结果为运行结果为参考自 参考自https://github.com/Advanced-F... 以下是一道异步的笔试题,写出运行结果: async function async1() { console.log(async1 start); await a...

    Tangpj 评论0 收藏0
  • promiseasync和await之执行顺序那点事

    摘要:是这样描述的函数中可能会有表达式,这会使函数暂停执行,等待表达式中的解析完成后继续执行函数并返回解决结果。返回值返回对象的处理结果。当执行到时,这个任务会被放入到回调队列中,等待调用栈有空闲时事件循环再来取走它。 原文地址:https://lvdingjin.github.io/tech/2018/05/27/async-and-await.html 故事要从一道今日头条的笔试题说起...

    高胜山 评论0 收藏0
  • 试题之Event Loop终极篇

    摘要:下面开始分析开头的代码第一轮事件循环流程整体作为第一个宏任务进入主线程,遇到,输出遇到函数声明,声明暂时不用管遇到,其回调函数被分发到微任务中。我们记为遇到,其回调函数被分发到宏任务中。 先上一道常见的笔试题 console.log(1); async function async1() { console.log(2); await async2(); con...

    233jl 评论0 收藏0
  • 一道试题引发Promise笔记

    摘要:对象是一个返回值的代理,这个返回值在对象创建时未必已知。这使得异步方法可以像同步方法那样返回值异步方法会返回一个包含了原返回值的对象来替代原返回值。 前言 近来参加校招笔试,发现有好几道关于Promise的题目。然而我都没有了解过。所以,这篇文章以网易笔试的一道题开始,记录关于Promise的那些事。文章地址:http://lsxj615.com/2016/08/04... 笔试题 c...

    _Suqin 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<