因此,为了开始并避免混淆,下面的代码引发了我的想法,除了一个解释我的问题来自哪里的例子之外,它对我的问题不一定有太大作用。
我只是在这里查看javascript中的一些代码: https://jsfiddle.net/Daniel_Hug/pvk6p/
var h1 = document.getElementsByTagName('h1')[0],
start = document.getElementById('start'),
stop = document.getElementById('stop'),
clear = document.getElementById('clear'),
seconds = 0, minutes = 0, hours = 0,
t;
function add() {
seconds++;
if (seconds >= 60) {
seconds = 0;
minutes++;
if (minutes >= 60) {
minutes = 0;
hours++;
}
}
h1.textContent = (hours ? (hours > 9 ? hours : "0" + hours) : "00") + ":" + (minutes ? (minutes > 9 ? minutes : "0" + minutes) : "00") + ":" + (seconds > 9 ? seconds : "0" + seconds);
timer();
}
function timer() {
t = setTimeout(add, .1);
}
timer();
/* Start button */
start.onclick = timer;
/* Stop button */
stop.onclick = function() {
clearTimeout(t);
}
/* Clear button */
clear.onclick = function() {
h1.textContent = "00:00:00";
seconds = 0; minutes = 0; hours = 0;
}
此人似乎使用递归来制作秒表,并在计时器中添加。
如果我以递归方式执行此操作,请将此函数更改为:
function timer() {
add();
}
占用堆栈空间,并最终中断,停止在3:00:00以下的地方。
然后我在原始代码中意识到他们使用setInterval(),它只创建一个单独的线程然后结束线程,释放堆栈空间。代码只重复执行此操作,这就是堆栈似乎没有溢出的原因。
我很难理解这是如何在较低级别上工作的?在我参加的一门课程中,我被要求制作自己的内存分配器(我理解占用堆空间),但我们从来不必担心线程,我想知道如何用它做这件事。
所以假设我有一个线程,然后内核切换到另一个线程,然后另一个线程,然后一个线程结束而另一个线程开始,我假设在线程结束和之间的堆栈中将存在间隙被创造,对吗?我在另一篇文章中读到(与java更相关,不确定编程语言是否重要)每个线程在堆栈上占用自己的空间。所以我想知道,每次我创建一个线程,它是否只是像内存分配器那样填补空白?如果一个帖子占用太多空间怎么办?该程序是否知道在其他地方重新分配内存?我在想这个错吗?
答案 0 :(得分:1)
Javascript是单线程的。例如,请参阅https://stackoverflow.com/questions/13504811。主要和单个javascript线程有一个就绪任务队列和一个定时任务队列。它循环遍历第一个队列,直到它为空,然后在第二个队列上循环,直到执行超出时间限制的所有定时任务,并且休眠直到出现新的就绪任务,或者某些定时任务的时间到来。
表达式setTimeout(add, .1)
只是将任务添加到定时任务的队列中。它将在超出.1
超时时执行,并且主线程能够执行下一个任务。