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

22 天前
 wefgonujnopu
有没有人会写的,看看 v 站有多少大神
要求:
await sleep(毫秒),让当前 async 函数进入等待,不能阻塞线程

提示: 实现起来非常简单,只要几行,不能使用任何库,要兼容浏览器环境
8761 次点击
所在节点    JavaScript
148 条回复
senjyougahara
21 天前
@EchoWhale #49 面试,让你手动实现一个 Promise A+
chesha1
21 天前
@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
21 天前
@chesha1 可以,新答案,虽然用了 promise 对象,但是是 api 间接调用的,我还不知道有这个方法呢,看了下是新出的
journalistFromHK
21 天前
哟吼 啥时候可以直接 return then 的 还是一直都可以?😂
wefgonujnopu
21 天前
@journalistFromHK 一直都可以,任何对象上添加一个 then 方法,都可以 await
wefgonujnopu
21 天前
@chesha1 你这函数貌似有问题,我试了 node22 运行立马就结束了,
hronro
21 天前
@fpk5 #14

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

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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1140531

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX