推荐关注
› Meteor
› JSLint - a JavaScript code quality tool
› jsFiddle
› D3.js
› WebStorm
推荐书目
› JavaScript 权威指南第 5 版
› Closure: The Definitive Guide
1sm23

看到一个面试题

  •  
  •   1sm23 · Mar 1, 2021 · 7250 views
    This topic created in 2076 days ago, the information mentioned may be changed or developed.
    函数在执行之后等待 3 秒返回 1,感觉是一个 js 事件的问题,想不出来😹
    Supplement 1  ·  Mar 2, 2021
    #19 那个能成,我就不贴出来了
    Supplement 2  ·  Mar 2, 2021
    审题!是 return 1
    settimeout 的别往下发了啊,settimeout 加到队列里,执行栈里的东西都跑完返回出来了
    45 replies  •  2021-03-11 18:41:42 +08:00
    jatai
    jatai
    Mar 1, 2021 via Android
    1
    ..... promise, setTimeout resolve
    leopod1995
    leopod1995
    Mar 1, 2021❤️1
    2
    ```js
    (()=>{
    setTimeout(()=> {
    return 1;
    }, 1000 *3)
    })()

    ```
    irytu
    irytu
    Mar 1, 2021 via iPhone
    3
    至少 setTimeout 应该想出来😂
    pkupyx
    pkupyx
    Mar 1, 2021
    4
    想起来个题还稍微复杂点:

    testFunc() {
    console.log("要求这句话立即输出",new Date());
    setTimeout(()=>{console.log("要求这句话 3 秒后输出",new Date());},1);
    // todo:要求不改动上面代码,这行后面写一段代码完成上面的需求。

    }
    autoxbc
    autoxbc
    Mar 1, 2021❤️1
    5
    @pkupyx #4 微任务阻塞宏任务?
    // todo
    const start = new Date();
    queueMicrotask( function callee(){
      if( new Date() - start < 3000 )
       queueMicrotask(callee);
    });
    murmur
    murmur
    Mar 1, 2021
    6
    @pkupyx 修改 console.log 的函数算么
    Kasumi20
    Kasumi20
    Mar 1, 2021❤️1
    7
    等待 3 秒后返回 1,一定是异步的,要么返回 Promise 要么延迟传递消息

    不可能同步地卡线程 3 秒

    接下来给出一个帅气的答案:
    async function sleepSync(n) { return new Promise(resolve => setTimeout(() => resolve(), n)); }

    async function task() {
    await sleepSync(3000);
    return 1;
    }
    ericls
    ericls
    Mar 1, 2021
    8
    这个需要写一个函数把主线程 block 3 秒,可能可以使用一些数学运算和循环之类的

    否则在 javascript 里面,很难 block 主线程
    ericls
    ericls
    Mar 1, 2021
    9
    @Kasumi20 你这个返回的是 promise
    @leopod1995 你这个返回 undefined
    Biwood
    Biwood
    Mar 1, 2021
    10
    @Kasumi20 #7
    我点了感谢,不过仔细想想好像也不符合题目描述,要求“返回 1”,严格来讲 async 函数返回的是 Promise 对象,而不是 1 。楼上说用 setTimeout 好像也不对,因为计时器的回调函数的返回值不是外层函数的返回值。这样看能只能用阻塞主线程,用 Date.now()计数 3 秒再返回。
    Biwood
    Biwood
    Mar 1, 2021
    11
    function foo() {
    const start = Date.now();
    while (Date.now() - start < 3000) {}
    return 1;
    }
    Kasumi20
    Kasumi20
    Mar 1, 2021
    12
    @ericls 敢在项目里动这种念头,你怕不是要被打屎
    ericls
    ericls
    Mar 1, 2021 via iPhone
    13
    @Kasumi20 这个题你还能怎么解? 自己改一个 runtime?
    Kasumi20
    Kasumi20
    Mar 2, 2021❤️1
    14
    @murmur #4

    这个可以根据变量提升原则来实现:

    console.log("要求这句话立即输出",new Date());
    setTimeout(()=>{console.log("要求这句话 3 秒后输出",new Date());},1);
    // todo:要求不改动上面代码,这行后面写一段代码完成上面的需求。

    function setTimeout(func) {
    globalThis.setTimeout(func, 3000);
    }
    1sm23
    1sm23
    OP
    Mar 2, 2021
    15
    @leopod1995 #2 你这个一执行就返回 undefined 啦
    KMpAn8Obw1QhPoEP
    KMpAn8Obw1QhPoEP
    Mar 2, 2021 via Android
    16
    @autoxbc 感觉这个靠谱
    gBurnX
    gBurnX
    Mar 2, 2021
    17
    最科学的方法 ,应该是把函数调用,改为框架调用。这样你就可以在框架里,利用各种 promise 、setTimeout 了。甚至还可以加入查询进度的功能。

    简单来说,把
    A 调用函数 B,改为

    A 调用框架 B 。并且把调用过程,改为 2 个过程:
    1.A 调用框架 B,并且发送参数、处理函数与回调函数。
    2.框架 B 开始执行处理函数,执行完毕后,开发可以利用任何方法,延迟 3 秒。
    3.延迟 3 秒后,框架 B 执行回调函数来通知 A 。
    4.在 2 与 3 之间,甚至 A 还可以调用框架 B,来查询处理进度。
    akatquas
    akatquas
    Mar 2, 2021
    18
    @leopod1995 你这返回值,被谁接住了? 谁能拿到这个返回的 1 ?
    cenbiq
    cenbiq
    Mar 2, 2021❤️5
    19
    fun block(){
    var startAt = Date.now()
    while(true) {
    if (Date.now() - startAt >= 3000) {
    return 1;
    }
    }
    }
    zzh7982
    zzh7982
    Mar 2, 2021
    20
    @cenbiq 同样的想法
    1sm23
    1sm23
    OP
    Mar 2, 2021
    21
    @cenbiq 直呼牛逼
    cczeng
    cczeng
    Mar 2, 2021
    22
    睡眠排序的兄弟?
    rodrick
    rodrick
    Mar 2, 2021
    23
    昨天问了我怎么在代码里区分是 http1 还是 2,回来查了一下就找到一个 window.chrome.loadTimes().connectionInfo
    togou
    togou
    Mar 2, 2021
    24
    return new Promise(r=>setTimeout(r(1),3000));
    zhuweiyou
    zhuweiyou
    Mar 2, 2021
    25
    await new Promise(resolve => setTimeout(resolve, 3000))
    1sm23
    1sm23
    OP
    Mar 2, 2021
    26
    @togou 不行,返回 Promise
    q673115816
    q673115816
    Mar 2, 2021
    27
    await new Promise(resolve => setTimeout(resolve, 3000, 1))
    pkupyx
    pkupyx
    Mar 2, 2021
    28
    卡死当前线程的都 OK,答案自己跑一下就试出来能不能过了,主要考察对 JS 线程与任务调度的理解。
    Balibabo
    Balibabo
    Mar 2, 2021
    29
    。。。这个需求用来骗甲方好给自己留有优化的余地么?直接阻塞线程可还行
    shilyx
    shilyx
    Mar 2, 2021
    30
    其实这个题在问:
    "既然你说你懂 JS,那么能否用 JS 证明你不懂 JS ?“
    cxe2v
    cxe2v
    Mar 2, 2021
    31
    @autoxbc
    @enchilada2020
    这代码跑了,不靠谱
    autoxbc
    autoxbc
    Mar 2, 2021 via iPhone
    32
    @cxe2v 那个代码是对 #4 题目的,不是楼主的题目
    cxe2v
    cxe2v
    Mar 2, 2021
    33
    @autoxbc 我就是对的 4 楼的题目跑的啊,不会间隔三秒输出,我在浏览器控制台跑的
    autoxbc
    autoxbc
    Mar 2, 2021 via iPhone
    34
    @cxe2v 那你再仔细检查一下吧,我在 firefox,vivaldi,node,deno 各跑了一次。另外为了排版,缩进那里有全角空格,要手工去掉
    libook
    libook
    Mar 2, 2021
    35
    理论上来说,3 秒后返回 1,应该是需要阻塞线程的,否则只能立即返回 promise,然后 3 秒后接收到值。
    lwlizhe
    lwlizhe
    Mar 2, 2021
    36
    好像 java 的类加载机制这块范例中有这种类似的,可惜这里是 js……
    djs
    djs
    Mar 2, 2021
    37
    var fun = () => {
    var star = new Date().getTime();
    let t = new Date().getTime();
    while (t - star < 3000) {
    t = new Date().getTime();
    }
    return 1;
    };
    djs
    djs
    Mar 2, 2021
    38
    @djs #37 我把线程阻塞掉 3s- -,不懂符不符合
    rrfeng
    rrfeng
    Mar 2, 2021
    39
    谁给我解释一下,这不就是个 sleep(3s) 的问题吗?还是我理解错了?

    js 里没法实现 sleep 吗?
    autoxbc
    autoxbc
    Mar 2, 2021
    40
    @rrfeng #39 js 可以 sleep,不过要用异步实现。异步的话原函数就需要先返回 promise,等 sleep 结束 resolve 出原始返回值

    而这里题目不允许修改函数返回值,也就不能异步,必须同步实现,只能用死循环阻塞住同步任务

    本质上不是问生产代码怎么写,而是加个不必要的预设,逼你用些奇技淫巧,目的是考察对任务调度的理解
    cxe2v
    cxe2v
    Mar 2, 2021
    41
    @autoxbc 好了,我找到我的问题出在哪儿了
    dd112389
    dd112389
    Mar 3, 2021
    42
    这个只能阻塞主线程来做吧, 异步基本都是在局部域里面, 拿不到返回值的.
    之前看过腾讯云的 cos sdk, 忘了是 v 几, 就是阻塞主线程等待对象初始化完毕.
    现在好像都改异步了.
    fy136649111
    fy136649111
    Mar 3, 2021
    43
    还可以这样
    function sleep(){
    Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 3000);
    }
    fy136649111
    fy136649111
    Mar 3, 2021
    44
    @fy136649111 function sleep(){
    Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 3000);
    return 1;
    }
    zeni123
    zeni123
    Mar 11, 2021
    45
    @cenbiq 是让用户等待三秒然后返回 1 哈哈哈 真等待 任何东西都要等待 不含糊
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1605 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 68ms · UTC 16:29 · PVG 00:29 · LAX 08:29 · JFK 11:29
    ♥ Do have faith in what you're doing.