我对 javascript 相当陌生,并且在对事件循环、回调队列和 webAPI 如何协同工作以在 Javascript 中实现异步有基本的了解之后。我有以下简单代码,包括 setTimeout 和 AJAX 来测试我对代码执行顺序的理解是否正确。
setTimeout(() => {
alert('timeout1')
}, 0);
req = new XMLHttpRequest();
req.open("get", "https://reqres.in/api/products/3");
req.onload = function(data) {
alert('request done'+data.target.responseText);
};
req.send();
alert('123');
alert('456');
alert('789');
hello,world
我期待结果是这样的:
警报('123') -> 警报('456') -> 警报('789') -> 警报('timeout1') -> 警报('请求完成')
我在想的是,首先setTimeout()
属于浏览器API,所以它会从javascript的调用堆栈中弹出并在javascript引擎之外执行,然后脚本继续执行下一行代码。当它到达这条线
req.send()
时,它也将在 javascript 引擎之外执行,然后脚本继续运行。
而且由于我将超时时间设置为0秒,所以setTimeout()
回调函数应该在回调函数()=>{alert('timeout1')}
之前先被推入回调队列(毕竟请求需要一些时间来等待响应,即使它非常快)。所以调用堆栈为空后的执行顺序是req.onload
function(){alert('request done');}
- 警报('timeout1')
- alert('请求完成')
但结果是:
alert('123') -> alert('456') -> alert('789') -> alert('request done') -> alert('timeout1')
显然我的想法是错误的。但我就是想不通。
如果我在这方面错了,请纠正我。感谢您检查我的问题!