Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/417.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript v8引擎是否先填满调用堆栈,然后运行代码?或者,它是在输入函数后立即运行代码吗_Javascript_Node.js_Asynchronous_Callback - Fatal编程技术网

Javascript v8引擎是否先填满调用堆栈,然后运行代码?或者,它是在输入函数后立即运行代码吗

Javascript v8引擎是否先填满调用堆栈,然后运行代码?或者,它是在输入函数后立即运行代码吗,javascript,node.js,asynchronous,callback,Javascript,Node.js,Asynchronous,Callback,以下是我尝试的代码: // **Creating variables and functions** let number_object = { num: 0 } function doHomework(callback) { //Starts doing the homework, supposed to finish after 5 seconds console.log("writing") setTimeout(() => {

以下是我尝试的代码:

// **Creating variables and functions**
let number_object = { num: 0 }

function doHomework(callback) {     //Starts doing the homework, supposed to finish after 5 seconds
    console.log("writing")

    setTimeout(() => {
        callback()
    }, 5000)
}

function Finished() {        //Called when 5 seconds are over
    console.log("Finished the homework")
}

function loop_(num_object) {  
    ++num_object.num;
    let i = 0;
    for (i = 0; i < 3000000000; ++i) { }
    console.log(`loop number ${num_object.num} over`)
}

// **Calling functions now**
doHomework(Finished)

let i = 0;
for (i = 0; i < 10000000000; ++i) { }  //This takes much more than 5 seconds
console.log(`This took more than 5 seconds, yet "finished" is not going to appear next`)

loop_(number_object)
loop_(number_object)
loop_(number_object)
loop_(number_object)
loop_(number_object)
loop_(number_object)
loop_(number_object)
loop_(number_object)
loop_(number_object)
loop_(number_object)

因此,我认为输出表明,代码首先将调用堆栈中的所有函数排队,然后运行它们。这就是为什么所有10个函数都在调用堆栈中排队,因此只有在它们完成后,“finished”(完成)才会出现,这称为再次进入事件循环之前的run to completion(运行到完成)

代码首先将调用堆栈中的所有函数排队,然后运行它们。这就是为什么所有10个函数都在调用堆栈中排队的原因


不,这10个函数没有在调用堆栈上排队。它们在程序代码中“排队”,如果有的话。只是你的大量增量操作没有在任何地方排队。它们在程序中编码,然后运行。

重要的是要记住,
setTimeout
不会调用传递给它的函数。相反,它保存了一个指向javascript稍后将在超时过期时调用的函数的指针

从这个意义上讲,javascript与Java、C/C++、Pascal、Python等语言没有什么不同。在所有这些语言中,如果您将函数指针保存到链接/列表或数组中,则该函数在稍后调用之前不会被调用。唯一的区别是,带有回调的API是javascript内置标准库的一部分。当然,这些API也存在于其他语言中,尤其是在GUI编程方面

就调用堆栈而言,javascript的行为通常与C/C++完全相同,但当涉及闭包时,它确实会变得怪异。使用闭包时,javascript的调用堆栈的行为类似于Lisp/Scheme、Haskell、Swift或Python

事件循环 重要的是要注意javascript是单线程的(有些人可能会声称不是这样——他们错了)。口译员的结构一般如下:

// Pseudocode

script_to_execute = compile_scripts();
event_handlers = [];

do {
    scheduled_callbacks = execute(script_to_execute)

    for each (callback in scheduled_callbacks) {
        event_handlers.push(callback)
    }

    event = wait_for_async_events()

    for each (callback in event_handlers) {
        if (callback.event == event) {
            script_to_execute = callback.script
        }
    }

}
while (event_handlers.length > 0)
因此,对
setTimeout
的调用基本上会将这些函数添加到事件处理程序列表中。您的整个脚本最初位于
script\u to\u execute
中。如果查看上面的程序流,很明显,只要脚本仍在执行,就不会处理任何事件。因此,javascript中的所有异步操作,包括
setTimeout
、HTTP请求、DOM更新等,都只会在脚本的最后一行之后发生


您还可以看到,所有这些都与调用堆栈或作用域无关。这只是时间安排——有些事情只是发生在未来而不是现在。

这是否回答了你的问题?Ty@Seblor我可能需要经历一段时间,因为我没有听说过微任务和宏任务。会让你知道你也可以阅读关于微任务的文档:虽然StackOverflow对我链接的问题的回答应该涵盖你的情况。@Seblor同时,我不是有意粗鲁,但是,你能告诉我首先发生了什么吗?对不起,我没有太多时间,但是如果你不明白接下来会发生什么,我今天晚些时候可以写一个答案,所以在运行之前,代码知道“我的第一项工作是完成代码中的函数”,并且无论调用什么,都会在前面的函数之后完成?是的。它甚至不只是关于函数,只是“完成这个代码”,包括例如< > 循环。C++和java也有闭包,对它们中的任何一个调用栈来说都没有什么特别之处。另一方面,Haskell的调用堆栈是一个非常不同的野兽,但更多的是因为thunks的惰性计算,而不是闭包。但是javascript作为一种语言既不是“单线程”也不是“多线程”。虽然ECMAScript没有为线程指定任何内置项,但它也不会阻止实现它们,并且存在在多个线程上运行javascript的运行时。@Bergi而ECMAScript没有指定单线程行为,而W3C和TwG在处理
setTimeout
之类的事情时会做什么,
fetch
等。对于
setTimeout
fetch
和其他异步内容,它们指定了一个事件循环,是的。对于web workers、
SharedArrayBuffer
s和atomics等,它们指定了多线程环境。
// Pseudocode

script_to_execute = compile_scripts();
event_handlers = [];

do {
    scheduled_callbacks = execute(script_to_execute)

    for each (callback in scheduled_callbacks) {
        event_handlers.push(callback)
    }

    event = wait_for_async_events()

    for each (callback in event_handlers) {
        if (callback.event == event) {
            script_to_execute = callback.script
        }
    }

}
while (event_handlers.length > 0)