为什么“asd”永远不会被打印并且相应的承诺永远不会解决?

问题描述 投票:0回答:1

我期望打印“asd”并承诺解决,但现实是不同的。代码卡在 while 循环中,并且“getI”始终返回 1,尽管它通过不同的方式进一步更改了几次。

let i = 1;

function getI() {
    return i;
}

new Promise( resolve => {
    while(getI() === 1) {

    }

    console.log('asd');
    resolve();
})

i = 2;

setTimeout(() => i = 3, 1500);

new Promise(resolve => {
    i = 4;
    resolve();
})

这一切背后的机制是什么?

javascript function asynchronous promise
1个回答
0
投票

在浏览器或 Nodejs 环境中运行 Javascript 的一些相关事实:

  1. Javascript 在单线程中运行 Javascript
  2. Javascript 是事件驱动的
  3. setTimeout()
    这样的函数只会通过事件循环触发回调函数
  4. while
    循环(不包含
    await
    )是Javascript中的阻塞结构,在
    while
    循环完成并将控制权返回到事件循环之前,其他任何操作都不能运行。

所以,考虑到所有这些,你的

while
循环就会永远运行。它占用了解释器,并且因为它占用了解释器并且没有其他东西可以运行,所以
i
的值永远不会改变,因此你的
while
循环永远无法完成并将控制权返回给事件循环。
setTimeout()
回调坐在那里等待在事件循环中运行,但永远不会运行,因为
while
循环永远不会将控制权返回给事件循环。
while
循环只是坐在那里并永远旋转,因为
while
循环内的代码不会导致
i
的值发生变化。

单线程、事件驱动代码的基本概念是解释器运行一段 Javascript 代码直到它返回。当它返回时,解释器返回到事件循环以查看还有什么正在等待运行,获取下一个事件,调用其回调,并类似地等待它返回,然后才能运行下一个事件。

像计时器这样的事件会排队,并且无法执行它们的回调,直到控制返回到事件循环并且直到它们在事件循环中轮到(因为其他事情可能会在它们之前运行)。

© www.soinside.com 2019 - 2024. All rights reserved.