V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
wefgonujnopu
V2EX  ›  JavaScript

js 不使用 promise 完成一个 sleep 函数,必须支持 await 调用

  •  
  •   wefgonujnopu · 2025 年 6 月 23 日 · 11697 次点击
    这是一个创建于 201 天前的主题,其中的信息可能已经有所发展或是发生改变。
    有没有人会写的,看看 v 站有多少大神
    要求:
    await sleep(毫秒),让当前 async 函数进入等待,不能阻塞线程

    提示: 实现起来非常简单,只要几行,不能使用任何库,要兼容浏览器环境
    第 1 条附言  ·  2025 年 6 月 24 日

    很多人说这个没用,还嘲讽深入理解,没有解决麻烦和任何问题
    我举个最简单的例子,python协程的async await,代码如下:

    import asyncio
    
    
    async def sleep(seconds):
        await asyncio.sleep(seconds)
    
    
    async def main(num=0):
        # 并发执行多个异步任务
        print(num)
        await sleep(0.0001)
        await main(num + 1)
    
    
    asyncio.run(main())
    
    

    输出到1000就会堆栈溢出,而用js的promise实现一样的函数,却不会
    然而一旦把sleep去掉,就会立马堆栈溢出

    function sleep(time){
        return new Promise(resolve => setTimeout(resolve, time));
    }
    
    
    async function main(num=0){
        console.log(num)
        //去掉sleep会堆栈溢出
        await sleep(1);
        await main(num+1)
    }
    
    main()
    

    因为js中的await实际上等效于then,也就是下面的代码,每次循环都是新的任务提交到事件循环队列,所以不会堆栈累加:

    async function main(num=0){
        console.log(num)
     
        sleep(1).then(()=>{
            main(num+1)  
        })
    }
    

    导致函数堆栈溢出的因素都可以说成不重要。没有任何意义,到底是自己没有认真学,还是真的不重要,各位自行判断吧

    第 2 条附言  ·  2025 年 6 月 24 日

    不要在说有什么用,有什么应用场景了,手写apply call bind这些面试题有应用场景吗?
    单纯为了兴趣研究下,就跟普通promise输出顺序的面试题一样,也可以写个类似的

    async function main() {
        await {
            then(func) {
                console.log(1)
                setTimeout(func,0);
                console.log(2)
            }
        }
        console.log(3)
    }
    
    main()
    
    ``
    148 条回复    2025-06-27 10:46:47 +08:00
    1  2  
    Zhuzhuchenyan
        1
    Zhuzhuchenyan  
       2025 年 6 月 23 日   ❤️ 17
    await 的 operand 只需要是一个 Thenable 就可以了
    wefgonujnopu
        2
    wefgonujnopu  
    OP
       2025 年 6 月 23 日
    @Zhuzhuchenyan nb ,这么快就有人答出来了
    wefgonujnopu
        3
    wefgonujnopu  
    OP
       2025 年 6 月 23 日
    对 promise 和 await 理解深入才能答出来。这个感觉可以当面试题,问 ai ai 都说做不到,还得提示下才回复正确答案
    yimity
        4
    yimity  
       2025 年 6 月 23 日
    yield 也应该可以实现。
    lscho
        5
    lscho  
       2025 年 6 月 23 日   ❤️ 5
    感觉 op 刚学 js 。。。。

    之前 es6 提案通过,但是未正式实现的时候,都是这样实现的
    Plumbiu
        6
    Plumbiu  
       2025 年 6 月 23 日
    @lscho es6 哪来的 async 和 await
    taotaodaddy
        7
    taotaodaddy  
       2025 年 6 月 23 日   ❤️ 1
    AI 没问题的,gemini 2.5 pro 明确回答 await 关键字实际上等待的并不仅仅是 Promise 对象,而是任何符合 "Thenable" 规范的对象

    它也完美得给出了与 1 楼基本相同的代码
    muzig
        8
    muzig  
       2025 年 6 月 23 日 via Android   ❤️ 2
    当面试回答的意义就是“深入理解”?🤔
    humbass
        9
    humbass  
       2025 年 6 月 23 日 via Android
    试了下用以下关键字问 AI (我手机上装了 7 种),只有 gemini, deepseek 回答正确。(ー_ー)!!

    ``` promp
    js 不使用 promise ,写一个支持 await 调用的 sleep 函数
    dcsuibian
        10
    dcsuibian  
       2025 年 6 月 23 日   ❤️ 20
    感觉你不适合当面试官。
    这个问题没有解决任何问题,徒增麻烦。
    lscho
        11
    lscho  
       2025 年 6 月 24 日
    @Plumbiu 有没有可能我说的是 Promise 对象。。。。op 的问题本质就是 Promise ,并不是 async 和 await 。async 和 await 只是一个语法糖而已。
    foolishcrab
        12
    foolishcrab  
       2025 年 6 月 24 日 via iPhone   ❤️ 2
    拿这个面试还不如直接问对方你们公司厕所纸用的什么品牌,这必须对你们公司有强烈意向以及惊人的观察力才能回答出来。对吧?
    fgwmlhdkkkw
        13
    fgwmlhdkkkw  
       2025 年 6 月 24 日   ❤️ 2
    茴有几种写法?
    fpk5
        14
    fpk5  
       2025 年 6 月 24 日   ❤️ 1
    中文提问 claude opus 4 回答不行,英文提问妙答正确答案。看来中文的训练语料库差距有点大,语言在 AI 时代仍然是个隔阂。
    wefgonujnopu
        15
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @dcsuibian 面试题不就是徒增麻烦的,手写 promise 没见过吗,有什么用,async await 本质上是语法糖,await xxx 实际上执行的就是 xxx.then(()=>{}),理解这个就能写出来,某些人学 promise 可能以为是线程,在阻塞的方法前面加 await 以为能异步的人也不少
    wefgonujnopu
        16
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @foolishcrab 对的,你们公司要招聘厕纸人才的话确实可以这样问
    wefgonujnopu
        17
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @lscho 确实是这样实现的,不过没有 await,用起来是回调地狱,这个考验你对 await 的理解而已,不是关键词,而是语法糖
    Sunzehui
        18
    Sunzehui  
       2025 年 6 月 24 日
    什么叫“让当前 async 函数进入等待,不能阻塞线程”?你听听说的是人话吗,真不怨 AI 答不出来,难道 JavaScript 是多线程语言?
    wefgonujnopu
        19
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @Sunzehui 懂了,js 没有线程,什么函数都不会阻塞线程,单线程语言没有线程的概念,怎么写都不会卡死,即使是 while 死循环
    windliang
        20
    windliang  
    PRO
       2025 年 6 月 24 日
    @wefgonujnopu #3 ChatGpt 4o 答案直接出来了
    wefgonujnopu
        21
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @windliang gpt 还是厉害的,我试了 grok 不行
    june4
        22
    june4  
       2025 年 6 月 24 日
    感觉是从别的会阻塞的真线程语言刚学 js 不到 10 分钟会问出来的问题
    wefgonujnopu
        23
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @june4 你怎么知道,我刚学 js 十秒
    passion336699
        24
    passion336699  
       2025 年 6 月 24 日
    之前看的一本什么书上讲过 “鸭式辨型”, 函数实现 thenable ,遵循 Promise A+,看起来像鸭子,那它就是一个鸭子
    songray
        25
    songray  
       2025 年 6 月 24 日
    手搓 Promise 是一道常见的面试题。
    https://febook.hzfe.org/awesome-interview/book1/coding-promise
    Cbdy
        26
    Cbdy  
       2025 年 6 月 24 日   ❤️ 1
    var Promise = require("bluebird");
    felbryiozzzz
        27
    felbryiozzzz  
       2025 年 6 月 24 日   ❤️ 1
    2025 年了还在自嗨这问题 哈哈哈哈
    burnsby
        28
    burnsby  
       2025 年 6 月 24 日   ❤️ 1
    会实现个这个就是大神了?这跟以前的'手撸一个 Promise'的问题有啥区别?知道这个就是大神了,那大神是多没有牌面?
    wefgonujnopu
        29
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @burnsby 所以我什么时候说知道这个就是大神了,我说的是知道这个就理解 promise 了而已
    wefgonujnopu
        30
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @felbryiozzzz 抱歉,忘记看日期了,2025 是出了什么新规定禁止讨论 promise 吗
    burnsby
        31
    burnsby  
       2025 年 6 月 24 日   ❤️ 7
    @wefgonujnopu ```有没有人会写的,看看 v 站有多少大神```不是你的第一句话?掘金这种地方比较适合你,去吧
    xiangyuecn
        32
    xiangyuecn  
       2025 年 6 月 24 日   ❤️ 2
    @songray #25 面试搞的就像上古时期要求兼容 IE6 一样
    wefgonujnopu
        33
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @burnsby 是啊,大神肯定会写啊,但是会写不一定是大神,逻辑学不好的话建议去学下
    mx1700
        34
    mx1700  
       2025 年 6 月 24 日 via Android   ❤️ 2
    啊???我还以为有啥高深的理解,仅仅是一个 Thenable ???稍微深入一点也应该是仅用 yield 怎么实现,再深入一点是连 yield 也用怎么实现
    slowgen
        35
    slowgen  
       2025 年 6 月 24 日   ❤️ 5
    没啥意义,qwen3-30B-A3B 的 4bit 量化在 M2 Ultra 上以 85 token/s 的速度秒了这一题,显存占用 18GB 左右。
    prompt:从架构师角度分析这个问题"js 不使用 promise 完成一个 sleep 函数,必须支持 await 调用,还要能在浏览器使用",本地不跑大模型可以去官网 https://chat.qwen.ai/

    当你掌握很多门语言之后,就知道那些屎一样的临时过渡方案就知道压根没必要看,JavaScript 的 async/await 都是抄 2012 年 C#发布的 5.0 语法,而且还没一次性抄对,中间搞那个 yield 恶心方案和过渡的 promise 方案,当时很流行的库有 co/bluebird/async 不知道有多少人记得。到了 2017 年 6 月 async/await 才正式并入规范,而 2017 年 5 月 Node.js 8.0 都正式支持 async/await 了,之前 6.x 都能通过参数开实验性支持了。

    我从 8.0 开始用 Node.js ,当时直接上 TypeScript 写后端,根本懒得吃那些设计缺陷造的屎,原型链和这种 then 地狱风格的代码压根没写过一行,项目规范都禁止写这种代码。

    至于你补充那个 python 例子,和异步也没啥关系,就一个默认递归深度,在带 GC 的语言中敢写递归之前不看限制或者有没有尾递归优化吗?
    wefgonujnopu
        36
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @mx1700 要支持 await ,肯定只能 thenable,yield 是做不到的
    Imindzzz
        37
    Imindzzz  
       2025 年 6 月 24 日   ❤️ 2
    感觉是为了这瓶答案包了这顿题目。。。
    想解决爆栈,用 setTimeout 或者尾调递归都可以的。
    kneo
        38
    kneo  
       2025 年 6 月 24 日 via Android
    深入理解茴字的第二种写法。
    wefgonujnopu
        39
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @shuimugan 是没啥关系啊,但是 js 里使用 await 之后确实不会堆栈溢出,重要的是这个,python 只是对比,正常来说都会堆栈溢出,所以 js 这点不一样
    wefgonujnopu
        40
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @Imindzzz 不是为了解决爆栈,只是研究下机制,而且 js 编译器没有实现尾递归,可以了解下
    lichuyi
        41
    lichuyi  
       2025 年 6 月 24 日
    === 问我茴香豆的茴有几种写法
    visper
        42
    visper  
       2025 年 6 月 24 日
    其实我觉得,知道 await 是在等待 Promise,是 promise 的语法糖,到这层就够开发用了。当然能手写一个 Promise 就更厉害点。至于 Thenable 这些。除了显得自己对 js 了解更多一点,其实没太多用处了。不了解也没什么。不过话说回来,招人么,同样的价钱,肯定先更厉害一点的。就像 java 那些,以前开始的时候,是大学毕业的随便问点 if else 什么的知道就行了,来了公司再学。现在呢,都想问 jvm 的了解程序啊 spring 源码啊的。
    felbryiozzzz
        43
    felbryiozzzz  
       2025 年 6 月 24 日   ❤️ 1
    @wefgonujnopu
    你如果是个技术向,你大可以去多研究算法/设计模式/编译这些更高级的领域,去做一些解决方案出来解决实际问题。不管是公司级别的还是前端通用的领域
    新语法出来是解决开发效率的,promise 给你了,async 给你了,规范制定者想,两者相结合异步的问题总该是都能解决了吧?好家伙,总有些大聪明想着我再用旧语法给你实现一遍,搞得我多理解这个语言语法一样。要是自己研究过了挺有成就感,还拿去面试别人,那只能说是真高人了
    burnsby
        44
    burnsby  
       2025 年 6 月 24 日
    @wefgonujnopu 我要笑死了,你问题里的不是`看看 v 站有多少大神会写的`,还搁这逻辑学呢。

    来,再给你贴个 AI 的回答。[img]( https://imgur.com/RNXDUyj)
    wefgonujnopu
        45
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @felbryiozzzz 抱歉,这就是新语法,await 没有旧语法,这只是另一种实现方式,旧的是 settimeout 回调
    SanjinGG
        46
    SanjinGG  
       2025 年 6 月 24 日 via Android
    又是这种 nc 面试题,如果 js 没有问题你问个瘠薄?你是面 js 还是面 python ?
    wefgonujnopu
        47
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @burnsby 我问的是,有没有人会写的,看看 v 站有多少大神,我有说会写=大神?你发的图都点不开,真的笑死了
    wefgonujnopu
        48
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @SanjinGG 就是 js 有问题,python 反而没问题,正常来讲都应该堆栈溢出,麻烦仔细看下
    EchoWhale
        49
    EchoWhale  
       2025 年 6 月 24 日 via iPhone
    什么场景下需要实现一个 sleep 但是不能用 promise ?
    wefgonujnopu
        50
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @EchoWhale 高性能场景,只需要返回一个 thenable 对象,promise 对象需要维护的状态更多,占用的空间更多
    Esec
        51
    Esec  
       2025 年 6 月 24 日 via Android
    当时甚至还有专门写一个延迟多少秒才返回的服务端来做计时的玩笑,只希望不要有人真拿这个当知识来记
    SanjinGG
        52
    SanjinGG  
       2025 年 6 月 24 日
    @wefgonujnopu ? js 到底用不用 sleep ?如果用 sleep 有什么问题?
    wefgonujnopu
        53
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @SanjinGG 和 sleep 没关系,是 await 的问题,每次调用都会把 await 下方的代码创建为任务,放到任务队列中,而不是从语言底层实现异步阻塞机制
    realJamespond
        54
    realJamespond  
       2025 年 6 月 24 日
    之前很多库的 promise 不是原生的
    horizon
        55
    horizon  
       2025 年 6 月 24 日
    @wefgonujnopu #48
    是你臆想的高性能场景,还是实际使用这种方法提升了性能?
    SanjinGG
        56
    SanjinGG  
       2025 年 6 月 24 日
    @wefgonujnopu js 单线程底层就是不支持系统级的 sleep ,你好像有点杠啊?
    cxe2v
        57
    cxe2v  
       2025 年 6 月 24 日
    八股文里的任务队列跟事件循环问题被你玩出花了,当赏
    wefgonujnopu
        58
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @SanjinGG 所以我什么时候说系统级了,我说的是语言底层,也就是 c++层?懂? python 的协程也是单线程,为什么可以?
    wefgonujnopu
        59
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @horizon 测试了下,原生的 promise 反而性能更高,v8 引擎有优化,原生 promise 为 c++对象,在 nodejs 中差别很明显,原生的快 2.5 倍左右,不过浏览器里面基本没区别,所以这个只能作为兴趣研究下
    oops2day
        60
    oops2day  
       2025 年 6 月 24 日
    好了,我承认是菜逼,要是面试遇到这题我指定不会,看了半天甚至没看懂题目要解决的问题。有没有屌大的给解释一下目的是啥。实际业务场景中会实现 op 举例的这种代码么,简化一下 Op 的代码本质上是递归,其实和异步或者说 promise 并没有关系。实现递归必须保证有结束分支不然就会死循环栈溢出这个应该是常识。 如果有实际业务应用的代码,请指教。 当然,如果说像楼上说的为了 thenable 这盘醋包的这个饺子,那确实值得大家这么嘲讽。 我很久没看了,以前刷八股文的时候我记得 thenable 是 promise 的规范还是啥的。
    Vegetable
        61
    Vegetable  
       2025 年 6 月 24 日   ❤️ 3
    我最讨厌的就是用犄角旮旯的知识点考察面试者还沾沾自喜。尤其是这种只能考察出 知道或不知道 的谜语人问题,出现在 100 分的面试题中顶多值 2 分。
    nexo
        62
    nexo  
       2025 年 6 月 24 日
    这个当面试题 面试的人真是倒了八辈子霉 到时候面试通过 去你代码库里这样写你又要不愿意了
    wefgonujnopu
        63
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @nexo 所以手写 promise 当面试题没问题吗,手写 promise 作为面试题,代码库里面就要用手写 promise?
    lianggggg
        64
    lianggggg  
       2025 年 6 月 24 日
    前端是真的闲的
    wefgonujnopu
        65
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @EgoTao 递归有溢出确实是常识,但是 js 代码中 await 函数就会破坏这种常识,加了就永远不会溢出
    oubenruing
        66
    oubenruing  
       2025 年 6 月 24 日
    @wefgonujnopu #50 有没有一种可能, 用了 await 但没有返回 promise 时,浏览器都会创建一个 promise 。
    Selenium39
        67
    Selenium39  
       2025 年 6 月 24 日   ❤️ 1
    跟中国考试不准用计算器一样如出一辙
    penzi
        68
    penzi  
       2025 年 6 月 24 日
    有一种大学生学 C 语言时候的热情。楼主没上过大学吧
    wefgonujnopu
        69
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @EgoTao
    比如下面这个代码,去掉 await foo(),就会堆栈溢出,如果不去掉,程序会一直运行到出现 fatal error FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
    ···
    async function foo() {
    return 1
    }


    async function main(num = 0) {
    //去掉 sleep 会堆栈溢出
    await foo()
    await main()

    }

    main()


    ···
    wefgonujnopu
        70
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @Selenium39 面试题不都这样,比如自己实现 apply call bind 这些
    Torpedo
        71
    Torpedo  
       2025 年 6 月 24 日   ❤️ 1
    所以我一直都说,面试是看缘分的。
    这样最好的标准就是 『你想不想和他一起工作』
    icy37785
        72
    icy37785  
       2025 年 6 月 24 日
    看到 op 这种帖子,我一般都是直接 block 的。但是我还是耐着性子看了一下,op 底下的一些回复,确定看到这种帖子确实应该直接 block 。op 还臆想出了一种“高性能场景”,给我整不会了。
    MzM2ODkx
        73
    MzM2ODkx  
       2025 年 6 月 24 日
    涨知识了,不过封装 sleep 函数不会比用 Promise 少多少字符
    coderunI
        74
    coderunI  
       2025 年 6 月 24 日   ❤️ 2
    所以,这段代码的深层意义在于:

    极简实现:它用最少的代码实现了一个可被 await 的异步延时操作。
    展示了 await 的本质:它清楚地表明了 await 的机制是基于 "Thenable" 接口的,而不是死板地绑定在 Promise 类型上。这对于深入理解 JavaScript 异步编程规范( Promise A+ 规范)非常有帮助。
    一种“炫技”或“教学”写法:在实际的团队项目中,为了代码的可读性和普适性,大家更倾向于使用 new Promise 的标准写法。而图片中的写法更像是一个精妙的例子,用来展示语言的内在机制。
    总结
    总的来说,这段代码的意义是:

    在功能上,它提供了一个简洁的 sleep 函数来暂停异步代码。
    在技术上,它是一个绝佳的范例,用最核心的方式展示了 await 关键字如何与任何拥有 then 方法的 "Thenable" 对象进行交互,而不仅仅是 Promise 对象。
    FlashEcho
        75
    FlashEcho  
       2025 年 6 月 24 日
    本前端菜鸡根本就没看懂你的问题,new Promise setTimeout 不行吗?

    稍微酷炫点的做法可以用原子量,不过一般 new Promise setTimeout 就够用了
    wefgonujnopu
        76
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @icy37785 所以你 block 之前还要回复下吗,上面已经说了,性能比原生的 promise 还慢,你确定耐着性子看了么,还是说也是自己臆想了下自己看过了,给我整不会了
    nexo
        77
    nexo  
       2025 年 6 月 24 日
    @wefgonujnopu 我没考过一道这种 除非真的是做很底层的库开发 考这些可能会有点用 用来锻炼思维
    lyxxxh2
        78
    lyxxxh2  
       2025 年 6 月 24 日
    我回答不出来,日常没用过这种。
    但是各种 promise 操作,还是随便玩的。

    https://www.v2ex.com/t/1031867
    我以前问别人的
    后端我倒是会问些框架原理。
    前端嘛 知道用法就行,我又不懂原理,也懒着要深入学习。
    kdwnil
        79
    kdwnil  
       2025 年 6 月 24 日 via Android
    高性能场景用 js ,这……对吗,自从发现 js 的时间间隔都做不到准确以后我就不在这种需求下玩弄 js 了
    wefgonujnopu
        80
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @kdwnil 对啊,你不知道 js 还有专门的 http 高并发优化的库吗,你小项目换语言容易,大项目可就要重构了,https://github.com/nodejs/undici
    senjyougahara
        81
    senjyougahara  
       2025 年 6 月 24 日
    @EchoWhale #49 面试,让你手动实现一个 Promise A+
    FlashEcho
        82
    FlashEcho  
       2025 年 6 月 24 日
    @chesha1 #75 哦我没看标题,不允许用 promise 啊,那用原子量,也很方便的

    ```javascript
    async function sleep(ms) {
    const _sleepBuffer = new SharedArrayBuffer(4);
    const _sleepView = new Int32Array(_sleepBuffer);
    const { value } = Atomics.waitAsync(_sleepView, 0, 0, ms);
    await value;
    }
    ```
    至少表面上没有出现 promise
    wefgonujnopu
        83
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @chesha1 可以,新答案,虽然用了 promise 对象,但是是 api 间接调用的,我还不知道有这个方法呢,看了下是新出的
    journalistFromHK
        84
    journalistFromHK  
       2025 年 6 月 24 日
    哟吼 啥时候可以直接 return then 的 还是一直都可以?😂
    wefgonujnopu
        85
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @journalistFromHK 一直都可以,任何对象上添加一个 then 方法,都可以 await
    wefgonujnopu
        86
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @chesha1 你这函数貌似有问题,我试了 node22 运行立马就结束了,
    hronro
        87
    hronro  
       2025 年 6 月 24 日
    @fpk5 #14

    我用中文没问题:
    FlashEcho
        88
    FlashEcho  
       2025 年 6 月 24 日
    @wefgonujnopu #86 不清楚啊,我也只是知道这个概念,原子量可以做 sleep 这个事,自己实际上没用过,上面这个代码是 ai 生成的,自己没试过
    sss393
        89
    sss393  
       2025 年 6 月 24 日
    这是在考我知不知道鸭子类型吗? JS 里只要实现 PromiseLike 就能被 await 吧。

    题外话:有时候真的很反感 js 生态圈的各种八股文写法,有没有人知道 python 和 go 的生态圈难道也这样吗。。。。
    wefgonujnopu
        90
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @sss393 js 主要是历史遗留问题,刚开始是 promise 先出现,await async 还没有,后面出了,不过实现方式是语法糖,本质上还是 promise,就跟继承和 class 一样,本质都是 function,压根没有 class,类似的问题还有很多,比如 undefined 可以作为关键词,let undefined = 0 都可以,所以实际项目如果要写 undefined,规范点都会让你写 void 0
    unco020511
        91
    unco020511  
       2025 年 6 月 24 日
    感觉这个问题应该是个好问题,因为我这个前端初学者看不懂
    lyxxxh2
        92
    lyxxxh2  
       2025 年 6 月 24 日   ❤️ 1
    @journalistFromHK
    await { then:(resolve) => resolve(1) }
    接收一个对象,果然。
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
    文档都写的,很少人会过一遍文档的。
    oops2day
        93
    oops2day  
       2025 年 6 月 24 日
    @wefgonujnopu #65 抛开 thenable 这个知识点跟你讨论哈,这个知识点你放我前几年刷八股文比较多的时候我大概率是能想到的,现在我确实没想到。 单说这个代码,就是我在业务中根本不会写出这种代码,那么它本身存在的意义并不大。如果放在 promise 规范里我觉得它也没有 promise 三个状态对于业务代码的帮助大。你下面列出来的代码,其实我在上面回复你之前自己验证过了,确实不会溢出,同样我也就比较好奇为什么不会溢出,还去 gpt 了一下。不会爆的本质就是 GC 了上一次的调用栈,所以理论上不会爆,整点闭包或者副作用多执行一会还是能爆的。
    uchihaObito
        94
    uchihaObito  
       2025 年 6 月 24 日
    async function sleep (ms) {
    const now = performance.now()
    while (performance.now() - now < ms) {}
    return void 0
    }
    lnbiuc
        95
    lnbiuc  
       2025 年 6 月 24 日
    带着答案找问题,没场景创造场景
    wefgonujnopu
        96
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @EgoTao 不会爆的本质是创建了微任务,而不是 GC 了,因为使用了 await,把下方的代码都包装为任务函数,添加到队列中稍后执行了,如果 GC 了,内存是不会溢出的,运行可以发现内存爆满,一瞬间几个 G ,业务中确实不会写出这种代码,因为不好维护,没意义,上面说了纯粹兴趣而已,就跟手写 apply call bind 和 promise 一样,也是面试题,但是实际项目不可能自己手写
    wefgonujnopu
        97
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @uchihaObito 你这个就是死循环了,阻塞线程的,sleep 过程中,进程直接卡死,所有异步任务停滞,而且 CPU 占用飙升
    wefgonujnopu
        98
    wefgonujnopu  
    OP
       2025 年 6 月 24 日
    @lnbiuc 确实没有场景,因为是 await 原理探讨,手写 promise 也没有场景,b 站这个教程视频一堆人看呢,场景就是面试会问,除此之外没有任何场景
    hengshenyu
        99
    hengshenyu  
       2025 年 6 月 24 日
    这个问题对于老前端来说太简单了
    deadpl
        100
    deadpl  
       2025 年 6 月 24 日
    因为 Python 没有尾递归优化,导致栈空间溢出,跟协程没关系。
    1  2  
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   2810 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 14:02 · PVG 22:02 · LAX 06:02 · JFK 09:02
    ♥ Do have faith in what you're doing.