📜  javascript 事件循环 - Javascript (1)

📅  最后修改于: 2023-12-03 15:16:09.579000             🧑  作者: Mango

Javascript 事件循环

Javascript 是一门单线程语言,也就是说在同一时间只能执行一个任务。但是在实际应用中,我们需要实现同时进行多个任务的效果,该如何处理呢?

Javascript 引入了事件循环机制(Event Loop),通过将任务分为同步任务和异步任务,来实现多个任务的同时执行。

同步任务与异步任务

同步任务 (Synchronous Task) 是指在执行期间阻塞代码的任务。也就是说,只有前面一个任务执行完毕,才能执行后一个任务。例如,下面的代码块中,第二行会等待第一行执行完毕后才会执行。

console.log('Hello');
alert('World');

异步任务 (Asynchronous Task) 是指不会阻塞代码的任务。当遇到异步任务时,不会等待它完成,而是立刻将其加入任务队列中,继续执行下面的代码。当异步任务完成时,再回调执行相应的操作。例如,下面的代码块中,setTimeout 是一个异步任务,alert 语句会立刻执行,而 console.log 会在 1 秒后执行。

console.log('Hello');
setTimeout(function() {
  console.log('World');
}, 1000);
alert('Hi');
事件循环机制

事件循环机制是一种在单线程中实现多任务的机制。其核心思想是,检查任务队列是否为空,如果不为空,就从队列头部取出一个任务,执行它。在执行过程中,如果任务是一个异步任务,就将它加入到事件队列中。执行同步任务的过程中,如果遇到了异步任务,也不会等待它完成,而是将其加入到事件队列中,在同步任务执行完毕后,再回头去执行事件队列中的异步任务。

具体来说,事件循环机制包括以下几部分:

1. 执行栈 (Call Stack)

执行栈是一个 LIFO (Last In First Out) 结构的栈,用于存储执行的上下文。每个上下文在被 push 到执行栈中时,都会被当作一个任务来执行。执行栈只能依次排队处理,一个任务执行完之后才会调用下一个任务。

2. 任务队列 (Task Queue)

任务队列用于存储异步任务。当异步任务完成时,就会将回调函数封装成一个任务,加入到任务队列中。每个任务都包含一个事件和一个回调函数。事件用于描述何时会触发回调函数。

3. 事件队列 (Event Queue)

事件队列用于存储由任务队列封装成的同步任务(也就是回调函数)。当所有的同步任务都被加入到事件队列中之后,事件循环机制会不断地从事件队列中取出一个任务,加入到执行栈的顶部,然后执行它。在执行过程中,如果遇到异步任务,就会将它加入到任务队列中。当执行栈为空时,事件循环机制会不断从事件队列中取出任务,加入到执行栈的顶部,然后执行它。这样循环往复,直到任务队列和事件队列都为空。

示例

下面是一个简单的示例,用来演示事件循环机制。

console.log('Hello');
setTimeout(function() {
  console.log('World');
}, 0);
console.log('Hi');

执行顺序如下:

  1. 执行栈:调用 console.log('Hello'),打印出 'Hello'
  2. 执行栈:调用 setTimeout,将回调函数和时间加入任务队列。
  3. 执行栈:调用 console.log('Hi'),打印出 'Hi'
  4. 执行栈:执行完毕,调用回调函数,将回调函数加入到事件队列中。
  5. 事件队列:取出一个任务,加入执行栈中执行。
  6. 执行栈:调用 console.log('World'),打印出 'World'
总结

Javascript 事件循环机制是一种进行多任务处理的方式,通过将任务分为同步任务和异步任务,来实现多个任务的同时执行。在执行过程中,所有的异步任务都被加入到任务队列中,执行完同步任务后,从事件队列中取出异步任务执行。通过使用事件循环机制,Javascript 可以充分利用单线程的特性,实现高效率的多任务处理。