永远不会调用异步函数的回调

时间:2017-01-23 19:25:12

标签: javascript asynchronous callback

我有这个函数,等待异步函数完成它的工作,然后返回。

function synchronous(){
    var notYet = true;

    setTimeout(function(){
        notYet = false;
    }, 1000);

    while(notYet)
        ;

    return "Done synchronously!";
}

console.log(synchronous());

这里使用synchronous循环停止函数while,直到执行异步函数(这里为setTimeout)的回调。但是,回调永远不会被调用(使用回调中的alert进行检查),因此,notYet将保持true并且函数循环将永远存在。那么,为什么在1000毫秒后没有调用回调呢?

注意:我不关心如何将异步函数转换为同步函数。我的问题是为什么回调没有被调用?

1 个答案:

答案 0 :(得分:6)

回调没有被调用,因为可以调用它的唯一线程被束缚在你的无限循环中。

在浏览器中,JavaScript在单个主UI线程上运行(加上您想要创建的Web工作者数量)。该线程在作业队列上运行:它获取要执行的作业(例如,处理单击),完成作业,然后返回以等待下一个作业。你用无限循环来阻止那个线程。计时器调度作业队列中的回调(可能是特定于实现的),但是线程永远不会完成当前作业(调用无限循环的作业),因此它永远不会接受下一个作业。

NodeJS还在一个线程中运行您的代码,同样的事情也是如此。 (并非所有环境都可以,但我不知道任何setTimeout没有在请求它的同一线程上安排定时器回调。)