如果这个问题的标题有点令人困惑,我很难道歉,我很难找到一种方法来说明这一点。
基本上,当调用异步函数时,如果从其他函数,对象或文件调用异步函数,代码将执行多远。例如:
function func1() {
// async function 1
// async function 2
}
function func2() {
// more code
}
func1();
func2();
假设我们执行func1()
并且其中的异步函数都需要很长时间才能运行。我们会在func2()
的内容仍在运行时继续func1()
,还是会阻止func1()
完成,然后再继续func2()
?
答案 0 :(得分:2)
JavaScript是单线程,非阻塞和异步语言。 JavaScript具有调用堆栈,事件循环和回调队列。字词直接来自this视频。 Javascript适用于v8引擎(chrome),蜘蛛猴(firefox),提供JavaScript 调用堆栈和堆。 v8或蜘蛛猴为Javascript提供调用堆栈,因此无论何时调用函数,它都存储在调用运行时堆栈(在我们的情况下为浏览器,如果安装了节点,则为本地)。浏览器还为setTimeOut
,XMLHttpRequest
和{{javascript等javascript提供网络api 1}}。图示是这样的。 (来源与我标记的视频相同。)
JavaScript 单线程,这意味着它可以一次执行一个函数,因为它只有一个调用堆栈。因此,每当执行异步代码(在func1内)时,它都是通过浏览器提供的webAPI来执行的。回调队列的作用来到这里。每当执行异步代码的结果时,它都存储在回调队列中,并等待堆栈变空(事件驱动编程)。每当它看到堆栈为空时,回调队列中的函数将开始执行。
在您的情况下,您正在调用DOM
,它会启动一些异步代码但当前func1
处于堆栈状态。如果异步代码已经完成,并且它看到堆栈为空,它将首先执行异步代码然后func1
,但如果func2
代码尚未完成,它将开始执行{{ 1}}并且回调队列将等待堆栈变空。在这种情况下,流程将为async
。
所以,这是时间问题。对于异步代码,如果代码已经返回并在回调队列中等待,只要它看到堆栈为空,它就会启动并开始执行func2
(.then或setTimeOut回调等)我会建议您观看该视频以获得更好的见解以及JS中的事件循环。如果我错过了某些内容,请随时编辑此答案或提供编辑建议。
答案 1 :(得分:0)
异步回调是顶级事件(类似于按钮单击事件),只能在没有其他脚本执行时启动。
执行将一直持续到调用堆栈为空(包括"全局用户代码"您的示例显示的内容)和脚本引擎本身得到控制 - 因此func1()
和func2()
将在回调执行之前完成。
注意:对于普通代码,您不能依赖此类行为 - 如果"异步"函数具有同步和异步代码分支来自该函数的回调可以同步执行,甚至不返回调用函数(这可以通过普通回调或包括promises在内的任何其他形式发生)。