Javascript 从不调用异步函数的回调

Javascript 从不调用异步函数的回调,javascript,asynchronous,callback,Javascript,Asynchronous,Callback,我有一个函数,它等待一个异步函数完成它的工作,然后返回 function synchronous(){ var notYet = true; setTimeout(function(){ notYet = false; }, 1000); while(notYet) ; return "Done synchronously!"; } console.log(synchronous()); 在这里,函数同步使用暂停,

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

function synchronous(){
    var notYet = true;

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

    while(notYet)
        ;

    return "Done synchronously!";
}

console.log(synchronous());
在这里,函数
同步
使用
暂停,同时
循环,直到异步函数的回调(在这里
设置超时
)得到执行。但是,永远不会调用回调(在回调中使用
警报检查
),因此,
notYet
将保持
true
,函数循环将永远运行。那么,为什么在1000毫秒后不调用回调呢


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

回调没有被调用,因为唯一可以调用它的线程正在执行无限循环

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


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

没有调用回调,因为唯一可以调用它的线程被无限循环占用

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


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

浏览器javascript是单线程语言浏览器javascript是单线程语言。然后我用递归函数替换了
while
循环,以提供执行回调的机会。但是没有起作用。如果你想看的话,我会发布代码。@ibrahimmahrir:递归函数也不会返回,它只会继续递归。想想看:如果<代码> Foo调用<代码> BAR < /C>,你不希望在中间发生一个让步(如果你写的是单线程代码,这比编写多线程代码要简单得多,因此这个模型在浏览器中使用)。code>foo
callling
foo
也不例外。让它返回的唯一方法是让它在代码末尾“脱落”。例如,把全局代码想象成一个函数调用。必须先退出该功能,然后才能选择下一个作业。之后,您得到的每个调用都将是回调(事件处理程序);在处理程序返回之前,线程无法从队列中提取下一个作业。是的,我现在知道Javascript是一种单线程语言,它是为我做的。我认为javascript是多线程的。我知道区别,我只是不知道JS是第一种类型。谢谢。@ibrahimmahrir:JavaScript不是单线程语言。这正是大多数(不是所有!)环境运行它的方式:每个全局环境一个线程。然后我用递归函数替换了
while
循环,以提供执行回调的机会。但是没有起作用。如果你想看的话,我会发布代码。@ibrahimmahrir:递归函数也不会返回,它只会继续递归。想想看:如果<代码> Foo调用<代码> BAR < /C>,你不希望在中间发生一个让步(如果你写的是单线程代码,这比编写多线程代码要简单得多,因此这个模型在浏览器中使用)。code>foo
callling
foo
也不例外。让它返回的唯一方法是让它在代码末尾“脱落”。例如,把全局代码想象成一个函数调用。必须先退出该功能,然后才能选择下一个作业。之后,您得到的每个调用都将是回调(事件处理程序);在处理程序返回之前,线程无法从队列中提取下一个作业。是的,我现在知道Javascript是一种单线程语言,它是为我做的。我认为javascript是多线程的。我知道区别,我只是不知道JS是第一种类型。谢谢。@ibrahimmahrir:JavaScript不是单线程语言。这正是大多数(不是所有!)环境运行它的方式:每个全局环境一个线程。