js sleep函数_atomic-sleep: 一个名副其实的JavaScript sleep函数

34ed46fa6beef65e5babaa130442a98f.png

某些情况下,我们需要让程序休眠一段时间再继续运行。

Node.js中通常的实现是这样的:

function 

如果你需要休息2秒,则这样使用:

// do something

但实际上该 `sleep` 函数只对当前调用有效,无法阻止其它异步函数的继续执行。一个简单的证明:

[

运行上述代码,终端上出现如下信息:

a9923b00cb3b9ccf88f02efa9f9fe663.png

我们看到,尽管 1 中调用了 sleep23 几乎也在同一时间在运行着。尽管我们一共调用了3次 sleep,但整个程序基本上在2秒内就运行结束了。简单的解释,就这是这个版本的 sleep 并不能阻止 event loop 继续运行。

那么问题是,有没有好的办法阻塞 event loop 呢?

Yes,有人写了 atomic-sleep 模块:

davidmarkclements/atomic-sleep​github.com
3346f95f62b48aa9741216f90d821cf6.png

作者对它的介绍是:

⏱️Zero CPU overhead, zero dependency, true event-loop blocking sleep ⏱️

即,零 CPU 开销、零依赖、真正阻塞event loop的sleep

将上面代码中的 sleep 替换成 atomic-sleep 中的实现。

const 

我们看看打印了什么:

2330cc26c057379267f753bb3e04798b.png

可以看到,整个过程用了6秒,1sleep 的过程中,23 被阻塞了。


源码解释

打开 atomic-sleep 模块的源码,在 index.js 文件中,我们看到其主要逻辑是依赖了 Atomics.wait 方法,该方法会监听一个Int32Array 对象的给定下标下的值,若值未发生改变,则一直等待(阻塞event loop),直到发生超时(由ms参数决定定):

const 

另外,模块还对低版本的 js 运行时做了兼容,如果不支持 Atomics,则改用一个占用CPU运行的方式:

function 

文章开头有说到,某些情况下,我们需要让程序休眠一段时间再继续运行。我提供一个具体的例子。

在写爬虫时,为了提升效率,我们通常会并发爬取一组网页。如果某个网页的请求返回了 429 异常码(Too Many Requests)。则休眠X秒再重试。我们已经知道基于 setTimeout 的休眠并不能阻止其它异步函数的执行(重试),这时 atomic-sleep 就派上用场了。

大致的爬取代码类似下面这样:

// 一组url

觉得有用?欢迎关注我的公众号,上面有更多技巧性文章!

2d605ab937b79b526ec891dba1de42c7.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值