看到一个面试题

2021-03-01 18:27:22 +08:00
 1sm23
函数在执行之后等待 3 秒返回 1,感觉是一个 js 事件的问题,想不出来😹
5213 次点击
所在节点    JavaScript
45 条回复
jatai
2021-03-01 18:32:54 +08:00
..... promise, setTimeout resolve
leopod1995
2021-03-01 19:14:02 +08:00
```js
(()=>{
setTimeout(()=> {
return 1;
}, 1000 *3)
})()

```
irytu
2021-03-01 19:26:40 +08:00
至少 setTimeout 应该想出来😂
pkupyx
2021-03-01 21:16:07 +08:00
想起来个题还稍微复杂点:

testFunc() {
console.log("要求这句话立即输出",new Date());
setTimeout(()=>{console.log("要求这句话 3 秒后输出",new Date());},1);
// todo:要求不改动上面代码,这行后面写一段代码完成上面的需求。

}
autoxbc
2021-03-01 22:55:25 +08:00
@pkupyx #4 微任务阻塞宏任务?
// todo
const start = new Date();
queueMicrotask( function callee(){
  if( new Date() - start < 3000 )
   queueMicrotask(callee);
});
murmur
2021-03-01 23:03:25 +08:00
@pkupyx 修改 console.log 的函数算么
Kasumi20
2021-03-01 23:21:24 +08:00
等待 3 秒后返回 1,一定是异步的,要么返回 Promise 要么延迟传递消息

不可能同步地卡线程 3 秒

接下来给出一个帅气的答案:
async function sleepSync(n) { return new Promise(resolve => setTimeout(() => resolve(), n)); }

async function task() {
await sleepSync(3000);
return 1;
}
ericls
2021-03-01 23:25:51 +08:00
这个需要写一个函数把主线程 block 3 秒,可能可以使用一些数学运算和循环之类的

否则在 javascript 里面,很难 block 主线程
ericls
2021-03-01 23:31:14 +08:00
@Kasumi20 你这个返回的是 promise
@leopod1995 你这个返回 undefined
Biwood
2021-03-01 23:42:41 +08:00
@Kasumi20 #7
我点了感谢,不过仔细想想好像也不符合题目描述,要求“返回 1”,严格来讲 async 函数返回的是 Promise 对象,而不是 1 。楼上说用 setTimeout 好像也不对,因为计时器的回调函数的返回值不是外层函数的返回值。这样看能只能用阻塞主线程,用 Date.now()计数 3 秒再返回。
Biwood
2021-03-01 23:44:14 +08:00
function foo() {
const start = Date.now();
while (Date.now() - start < 3000) {}
return 1;
}
Kasumi20
2021-03-01 23:44:28 +08:00
@ericls 敢在项目里动这种念头,你怕不是要被打屎
ericls
2021-03-01 23:58:05 +08:00
@Kasumi20 这个题你还能怎么解? 自己改一个 runtime?
Kasumi20
2021-03-02 00:01:29 +08:00
@murmur #4

这个可以根据变量提升原则来实现:

console.log("要求这句话立即输出",new Date());
setTimeout(()=>{console.log("要求这句话 3 秒后输出",new Date());},1);
// todo:要求不改动上面代码,这行后面写一段代码完成上面的需求。

function setTimeout(func) {
globalThis.setTimeout(func, 3000);
}
1sm23
2021-03-02 00:10:54 +08:00
@leopod1995 #2 你这个一执行就返回 undefined 啦
enchilada2020
2021-03-02 00:13:49 +08:00
@autoxbc 感觉这个靠谱
gBurnX
2021-03-02 00:47:30 +08:00
最科学的方法 ,应该是把函数调用,改为框架调用。这样你就可以在框架里,利用各种 promise 、setTimeout 了。甚至还可以加入查询进度的功能。

简单来说,把
A 调用函数 B,改为

A 调用框架 B 。并且把调用过程,改为 2 个过程:
1.A 调用框架 B,并且发送参数、处理函数与回调函数。
2.框架 B 开始执行处理函数,执行完毕后,开发可以利用任何方法,延迟 3 秒。
3.延迟 3 秒后,框架 B 执行回调函数来通知 A 。
4.在 2 与 3 之间,甚至 A 还可以调用框架 B,来查询处理进度。
akatquas
2021-03-02 10:05:38 +08:00
@leopod1995 你这返回值,被谁接住了? 谁能拿到这个返回的 1 ?
cenbiq
2021-03-02 10:29:16 +08:00
fun block(){
var startAt = Date.now()
while(true) {
if (Date.now() - startAt >= 3000) {
return 1;
}
}
}
zzh7982
2021-03-02 10:32:46 +08:00
@cenbiq 同样的想法

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

https://www.v2ex.com/t/757386

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

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

© 2021 V2EX