怎么可能?事件循环让它成为可能。
在开始之前,让我们定义事件循环运行的环境。我们假设我们正在处理浏览器(不在Node或其他环境中)执行的Javascript代码。
首先我们来认识下故事中的主角:
调用栈 (the call stack)
Web API
消息队列 (message queue)
事件循环 (the event loop)
这是浏览器环境
接下来开始JS故事 让我们看看下面的代码,看看会发生什么
调用foo函数,结果是:
> One
> Three
> Two
现在,让我们看看我们的主角试图执行上述代码:
首先,浏览器发生foo()调用堆栈的函数调用;
console.log("One")语句被推到前一帧的顶部;
setTimeout()语句发送到堆栈;
setTimeout;
foo ()函数的语句,也是就是这里的最后一个;
让我们回到 web API,它为回调函数设置了一个计时器。现在计时器已经结束,浏览器将回调消息发送到消息队列
foo()函数声明中没有其他内容时,最早的foo()帧也将从调用堆栈中删除!
现在,事件循环可能更幸运
并将消息的相关函数发送到调用堆栈;
总结: 语言本身没有任何异步内置。环境(浏览器等)是安排导致异步执行的事件的环境(使用回调,promises、ajax 调用等)