吾爱咖啡 发表于 2021-9-16 11:29

想写个在JS里能随便调用的sleep()函数?【油猴】

本帖最后由 吾爱咖啡 于 2021-9-16 15:44 编辑

最近在写油猴脚本,想写个sleep()函数。
先是用setTimeout写了个简单的,发现不管用。猜测可能是因为setTimeout类似异步。然后找啊找,最后写出如下代码,发现还是不行,感觉还是没有一点停顿(顺便描述一下我使用sleep的环境):
(function() {
    'use strict';
    // 一些定义和声明
    function sleep(time, unit){
      if(time == null){time = 5000;}//我想不带参数的时候就默认5秒
      if(unit != null){time = time * 1000;}//我想这个参数是任意字符时,前面的就是秒,当然,真要在别处用,这里要再改改
      for(var t = Date.now();Date.now() - t <= time;);
    }
    setInterval(a, 30000);
    setInterval(b, 20000);
    function a(){
    //balabala
    sleep();
    //balabala
    }
    function b(){}
})();
网上找到有好几种sleep的写法,但用起来都挺复杂。要么是这种:sleep(function, time),但我只是单纯想暂停几秒而已啊。要么是async/await组合,我要sleep的地方挺多,每次都要打await sleep()感觉有点麻烦,还必须在async function()里。
我就想能不能有个在哪都能调用的sleep()函数?
【已解决】
方法在4楼
最终的我的代码在7楼

Su、 发表于 2021-9-16 11:40

用setTimeout

无阻 发表于 2021-9-16 11:46

因为JavaScript引擎只有主线程..

你在js里面sleep会导致整个网页都要sleep之后才能活动

所以不支持sleep写法..

纸偶 发表于 2021-9-16 12:39

(async function () {
      'use strict';
      async function sleep(ms) {
            return new Promise((resolve) => setTimeout(resolve, ms));
      }

      ...
      await sleep(4000); //暂停4秒
      ...
    })();

把全部代码放在一个立即执行的async函数里,然后在需要暂停时直接 await sleep();就行了

涛之雨 发表于 2021-9-16 13:25

4楼说的方法也可以
我的想法是封装一个Promise,
然后.then嵌套

吾爱咖啡 发表于 2021-9-16 14:56

无阻 发表于 2021-9-16 11:46
因为JavaScript引擎只有主线程..

你在js里面sleep会导致整个网页都要sleep之后才能活动


我知道JS里没有原生的sleep,所以才要自己写嘛。
不过你的话提醒了我,会不会是实际sleep了,但整个网页都阻塞了,所以看起来好像没有停顿一样。
然后我拿秒表测试了一下,好像确实是这样的。
而之所以用秒表,是因为用下面的代码,并没有弹出提示,是哪里错了吗?
function sleep(time, unit){
    if(time == null){time = 1000;}
    if(unit != null){time = time * 1000;}
    GM_notification({text: Date.now(), title: '测试'});
    for(var t = Date.now();Date.now() - t <= time;);
    GM_notification({text: Date.now(), title: '测试'});
}

吾爱咖啡 发表于 2021-9-16 15:24

本帖最后由 吾爱咖啡 于 2021-9-16 15:32 编辑

纸偶 发表于 2021-9-16 12:39
[编辑的时候总出错,我就删了这里](async function () {
      'use strict';
      async function sle ...
我尝试了下,由于我的sleep是在另一个函数里(如我的代码),必须是async function a()才行,最外层是不是async函数倒无所谓。
谢谢,根据你的,我实现了我想要的,看得见的暂停。
(function() {
    'use strict';
    ...
    async function sleep(time, unit){
      if(time == null){time = 5000;}//我想不带参数的时候就默认5秒
      if(unit != null){time = time * 1000;}//我想这个参数是任意字符时,前面的就是秒,当然,真要在别处用,这里要再改改
      return new Promise(resolve => {setTimeout(resolve, time);})
    }
    setInterval(a, 30000);
    setInterval(b, 20000);
    async function a(){
      ...
      await sleep();
      ...
    }
    function b(){}
})();

吾爱咖啡 发表于 2021-9-16 15:40

涛之雨 发表于 2021-9-16 13:25
4楼说的方法也可以
我的想法是封装一个Promise,
然后.then嵌套

大佬,你的方法我也搜到过,但搞嵌套好像挺麻烦的。
4楼的方法其实也搜到过,也试过,但用法不正确,没实现我要的功能,就先丢一边了。正确使用后,现在可以了。
其实这次发帖还想看看有没有最方便的方法(直接sleep(1000)这样的)。目前来看,4楼的方法已经是最简单的了。

ningg 发表于 2021-9-16 16:12

感谢分析

魔幻冰扬 发表于 2021-9-16 16:15

前端面试题: 如何实现一个sleep函数
页: [1] 2
查看完整版本: 想写个在JS里能随便调用的sleep()函数?【油猴】