Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.6k views
in Technique[技术] by (71.8m points)

请问为什么这个async function 堵塞了?如何让他不堵塞呢?

他不输出 console.log, 如果屏蔽 main 方法则会输出,这是为什么呢?

如何让他不堵塞呢?

function sleep(numberMillis) {
  var now = new Date();
  var exitTime = now.getTime() + numberMillis;
  // eslint-disable-next-line no-constant-condition
  while (true) {
    now = new Date();
    if (now.getTime() > exitTime) return;
  }
}

async function main() {
  while (true) {
    await sleep(3000);
  }
}

main();

setInterval(() => {
  console.log("---");
}, 1000);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

看了一下题主和楼上的对话,揣测题主是想做一个生产者-消费者模型。
其实所有的JS线程天生就是消费者线程。这是因为线程背后有一个事件循环机制在默默地搜集所有应当执行的任务,然后把这些任务排好队依次执行,可以说这个机制就是对应的生产者。专业的解释可以参考 JavaSctipt-MDN:并发模型与事件循环
开发者如要添加新的任务,只需要把对应的函数作为回调函数传递给某个事件的接口,这个事件触发之后,回调函数就被添加到任务队列里了。开发者不能也不需要使当前线程“休眠”,通过死循环阻塞线程的“休眠”,实际上是给线程添加了一个执行时间极长的“大型”任务,持续消耗计算资源,在浏览器中执行这样的代码可能会导致浏览器假死乃至崩溃。
总而言之,题主要做的事情就是监听主线程的投喂(这里应该是process.onmessage事件),然后调用函数处理,处理完再通过消息机制把结果传给主线程。
如果题主想要自己调度一个队列的话,可以使用生成器函数定义一个类似协程的调度方案,不过有点多余,因为到最后还是要借助事件循环机制来唤醒“协程”。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...