
本文共 1258 字,大约阅读时间需要 4 分钟。
JavaScript
是一种单线程语言,`ereignah起250px; background:#f5f5f5; border:1px solid #ddd; padding:10px; border-radius:4px;">
JavaScript语言是一门“单线程”的语言,
` `不像Java语言,类继承Thread再来个thread.start就可以开辟一个线程。
` `所以,JavaScript就像一条流水线,仅仅是一条流水线而已,要么加工,要么包装,不能同时进行多个任务和流程。
` `“同步”——一下就让人想到“一起”这个词;
` `“异步”呢,从字面来看,好像是在不同的(异)的方式上进行操作,
` `那让我想想,最常见的“一边...一边...”是否是异步的正确描述?比如‘小明一边吃雪糕一边写作业’,看起来没问题,但实际上这不是正确的异步概念!
` `事实上,同步和异步的区别在于在单线程环境下,两个任务的执行顺序不同。
` `最基础的异步操作体现在`setTimeout`和`setInterval`函数中。很少有人真正理解它们的异步性,尽管它们能够控制JavaScript的执行顺序,实现任务调度。
` `比如说以下代码:
console.log("1");
setTimeout(function() { …… }, 0);
同样是设置延迟时间为0的`setTimeout`函数,其作用是在指定的时间点执行函数的逻辑,但实际上,这些函数会被排队到任务队列中,等待当前执行栈空闲时再被处理。
从运行结果来看,尽管设置了延迟时间为0,依然遵循任务队列的执行顺序,输出结果可能是1, 2, 3, 4, 5,而不是在定时的时间点执行函数的预期顺序。这就解释了为什么尽管延迟时间很短,函数依然会被排队执行。
任务队列的背后是浏览器的事件循环机制。所有同步任务都会在执行栈(Execution Context Stack)中执行,当执行栈空闲时,系统会去读取任务队列(Task Queue),逐个取出事件并从中获取相应的回调函数,执行这些异步任务。
要理解事件循环,我们需要认识到浏览器的主线程无法同时处理多个任务,它会将所有耗时操作排队。当处理完同步任务后,主线程会去处理任务队列中的事件。这就形成了JavaScript的单线程异步调度机制,确保程序不会因为某个操作长时间卡住,而忘记处理其他重要的任务。
从任务队列来看,除了网络操作的回调函数之外,还有其他类型的事件回调函数会被存储在其中。例如,用户点击页面的按钮或滚动屏幕,这些事件也会对应相应的回调函数,从而被加入任务队列,等待执行。
最重要的是,理解回调函数的作用。每当发生某些特定事件时,定义的回调函数会被附加到任务队列中。当事件循环机制检测到任务队列有事件需要处理时,它就会将相应的回调函数从队列中取出并执行。这样,主线程就能在适当的时候处理这些耗时的操作,而不阻塞整个程序运行。
发表评论
最新留言
关于作者
