看到一段代码, setTimeout(resolve, 0), 不是很明白用意? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yazoox
V2EX    React

看到一段代码, setTimeout(resolve, 0), 不是很明白用意?

  •  
  •   yazoox 2021-09-0117:39:45 +08:00 3818 次点击
    这是一个创建于 1550 天前的主题,其中的信息可能已经有所发展或是发生改变。
    const whenStable = async () => await act(async () => { await new Promise((resolve) => setTimeout(resolve, 0)); }); 

    原帖地址: https://stackoverflow.com/questions/60137762/how-can-i-test-a-react-hooks-component-by-changing-usestate?rq=1 只有一个回复,回复里面的测试文件,里面用到了这个

    不是很理解这个的用意。如果说需要延时,那为什么 setTimeout 的参数是 0? 还是说,作者只是举个例子?应该设为比如 500,etc.?

    以及,这个貌似有 warning

    Warning: The callback passed to ReactTestUtils.act(...) function must not return anything. 
    15 条回复    2021-09-03 13:08:04 +08:00
    Puteulanus
        1
    Puteulanus  
       2021-09-01 17:43:46 +08:00
    setTimeout 0 不是精确的没有延迟,看这意思是想等待到下个 event loop ?
    just1
        2
    just1  
       2021-09-01 17:43:57 +08:00
    类似于 nextTick
    misdake
        3
    misdake  
       2021-09-01 17:46:37 +08:00   1
    microtask 和 macrotask 的区别吧。promise 是 microtask 。setTimeout 是 macrotask,会在所有 promise 执行之后再执行。
    感觉原因应该是:界面变动都是通过 microtask 来实现的,setTimeout 的函数一旦运行就说明已全部执行完毕。
    RexG
        5
    RexG  
       2021-09-01 18:09:01 +08:00
    @just1 @misdake 说的都对,就是这个操作
    eason1874
        6
    eason1874  
       2021-09-01 18:14:28 +08:00   1
    用途是防阻塞。

    浏览器是按顺序处理事件的,setTimeout 回调事件排在页面普通 Javascript 代码后面,所以比较占时间的 Javascript 可以放到 setTimeout 里面,等页面渲染好再去执行,防止阻塞导致白屏什么的。

    setTimeout 不是真正的定时任务,意思是最快在这个时间执行,慢的话,说不准。如果前面事件有阻塞一辈子,那一辈子也不会执行。
    KouShuiYu
        7
    KouShuiYu  
       2021-09-01 18:15:52 +08:00
    估计是确保 DOM 已经更新
    violetlai
        8
    violetlai  
       2021-09-01 19:39:41 +08:00
    有些插件需要等 dom 更新 才搞这个
    2i2Re2PLMaDnghL
        9
    2i2Re2PLMaDnghL  
       2021-09-01 19:51:53 +08:00
    我觉得取个名字清楚点
    const nexttick = () => new Promise((resolve) => setTimeout(resolve, 0));

    //...
    await nexttick()
    //...

    至于你的 warning,则是来源于 act(async () => {}) 这部分。但理论上来说这段中确实不包含任何 return,是不是返回了一个 Promise<undefined> 的原因?
    wanguorui123
        10
    wanguorui123  
       2021-09-01 20:01:18 +08:00
    添加到事件队列末尾下个周期调用
    slime7
        11
    slime7  
       2021-09-01 20:39:38 +08:00
    我去抄 vuetify 的水波纹代码时也见过这个用法,用在添加水波纹动画的进入 class 上,我当时猜测是需要先设置一个初始样式,再用这个方式设置需要变形到的样式,这样才能产生 css 的 transition
    Taikyo
        12
    Taikyo  
       2021-09-01 22:40:43 +08:00
    加入宏任务,只是为了不让它被立刻执行,可以在下一个 event loop 去执行。
    xxz0315
        13
    xxz0315  
       2021-09-02 13:00:00 +08:00
    相当下一帧的意思
    yazoox
        14
    yazoox  
    OP
       2021-09-02 20:03:16 +08:00
    @2i2Re2PLMaDnghL
    有没有办法修改一下,消除这个警告?就按当前的用途
    2i2Re2PLMaDnghL
        15
    2i2Re2PLMaDnghL  
       2021-09-03 13:08:04 +08:00
    @yazoox 简单地
    act(async()=>{...})
    转化为
    act(()=>{(async()=>{...})()})

    但其实没有任何意义,是这个 warning 本身有问题。
    我猜想这个 warning 的设置似乎是为了避免有人「想当然地」用 act callback 传递测试失败信号。
    为了绕过一个过于宽泛的 warning 这么做不好,你应当修正 warning 的提供者。
    看上去这个 warning 不是 react 提供的,在 react 代码中全文搜索 "must not return anything" 类似文字均在处理要求 effect 只能返回一个函数。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2504 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 04:33 PVG 12:33 LAX 20:33 JFK 23:33
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86