Javascript setTimeOut真的是异步的吗?
我正在开发TestNodeJS应用程序,我想创建100个“线程”,每个线程都使用setTimeOut在某个随机时间执行Javascript setTimeOut真的是异步的吗?,javascript,node.js,multithreading,asynchronous,Javascript,Node.js,Multithreading,Asynchronous,我正在开发TestNodeJS应用程序,我想创建100个“线程”,每个线程都使用setTimeOut在某个随机时间执行 let count = 10; let counter = 0; for(let i = 0; i < count; i++) { // call the rest of the code and have it execute after 3 seconds setTimeout((async () => { counter++
let count = 10;
let counter = 0;
for(let i = 0; i < count; i++) {
// call the rest of the code and have it execute after 3 seconds
setTimeout((async () => {
counter++;
console.log('executed thread',i, 'current counter is',counter);
if(counter === count){
console.log('all processed');
}
}), Math.random()*10);
console.log('executed setTimeOut number ',i);
}
console.log('main thread done, awaiting async');
我所期望的是混合执行的
线程X当前计数器是Y
在执行的setTimeOut编号Z
之间,为什么它似乎首先将所有调用添加到setTimeOut中,然后才执行它们?即使我将计数设置为1000000,这种情况仍在发生。对我来说,这看起来不像是预期的行为。对setTimeout
的调用是同步发生的。然后,运行时会有一堆“任务”排队,可以在以后执行。当超时过期时,这些任务可以由运行时自由选择并执行。因此,所有“executed setTimeOut number”消息首先出现,然后是“executed thread…”。对setTimeOut
的调用同步发生。然后,运行时会有一堆“任务”排队,可以在以后执行。当超时过期时,这些任务可以由运行时自由选择并执行。因此,所有的“已执行设置超时数”消息首先出现,然后是“已执行线程…”。设置超时的创建不是异步的。Async只是意味着它可以异步运行。它不一定需要它,除非你特别地让线程休眠。是的,我理解,我一个接一个地同步调用setTimeOut。但是当我第一百万次调用setTimeOut时,我希望至少已经执行了一些定时函数。为什么不会发生这种情况?循环在一个循环中按顺序设置所有函数,它们或多或少会被随机调用,但它们都有一个全局计数器的闭包,全局计数器按顺序计数。@TomášNavara Javascript只有一个线程。因此,首先执行for循环。在for循环完成之前,不会发生其他任何事情。当没有其他情况发生时,引擎将检查是否有超时的内容,如果是,则运行它。您创建的设置超时不是异步的。Async只是意味着它可以异步运行。它不一定需要它,除非你特别地让线程休眠。是的,我理解,我一个接一个地同步调用setTimeOut。但是当我第一百万次调用setTimeOut时,我希望至少已经执行了一些定时函数。为什么不会发生这种情况?循环在一个循环中按顺序设置所有函数,它们或多或少会被随机调用,但它们都有一个全局计数器的闭包,全局计数器按顺序计数。@TomášNavara Javascript只有一个线程。因此,首先执行for循环。在for循环完成之前,不会发生其他任何事情。当没有其他情况发生时,引擎将检查是否有超时的内容,如果是,则运行它。但如果使用计数器=10000000,我希望看到至少一些定时函数的输出在这两者之间混合。因为这是设置超时的时间点,不是吗?它应该在被调用时启动计时器,并且在整个10000000循环被循环之前,这个计时器肯定会滴答作响through@TomášNavara-不,Javascript是单线程的(除非您使用特定的线程框架,例如web workers)。在现有前台任务完成之前,无法执行异步任务。具体来说,您的任务可以在指定的超时过期后的任何时间执行,但不能保证在超时后立即启动,因为可能需要先完成其他任务。因此,如果我设置一个计时器,然后做一些需要1分钟才能完成的事情,那么计时器将在放置后1分钟+超时内滴答响?@TomášNavara yes,setTimeout将事情放入队列中,直到当前线程完成后才能运行。当其他任务正在运行时,不会执行任何超时,它们必须至少等待分配的时间,然后找到运行的机会。但是如果我使用counter=10000000,我希望至少看到一些定时函数的输出在这两者之间混合。因为这是设置超时的时间点,不是吗?它应该在被调用时启动计时器,并且在整个10000000循环被循环之前,这个计时器肯定会滴答作响through@TomášNavara-不,Javascript是单线程的(除非您使用特定的线程框架,例如web workers)。在现有前台任务完成之前,无法执行异步任务。具体来说,您的任务可以在指定的超时过期后的任何时间执行,但不能保证在超时后立即启动,因为可能需要先完成其他任务。因此,如果我设置一个计时器,然后做一些需要1分钟才能完成的事情,那么计时器将在放置后1分钟+超时内滴答响?@TomášNavara yes,setTimeout将事情放入队列中,直到当前线程完成后才能运行。当其他任务正在运行时,不会执行任何超时,它们必须至少等待分配的时间,然后找到运行的机会。
executed setTimeOut number 0
executed setTimeOut number 1
executed setTimeOut number 2
executed setTimeOut number 3
executed setTimeOut number 4
executed setTimeOut number 5
executed setTimeOut number 6
executed setTimeOut number 7
executed setTimeOut number 8
executed setTimeOut number 9
main thread done, awaiting async
executed thread 5 current counter is 1
executed thread 1 current counter is 2
executed thread 4 current counter is 3
executed thread 9 current counter is 4
executed thread 6 current counter is 5
executed thread 2 current counter is 6
executed thread 3 current counter is 7
executed thread 8 current counter is 8
executed thread 0 current counter is 9
executed thread 7 current counter is 10
all processed