事件循环

浏览器多进程架构,其中渲染进程负责渲染页面。每个渲染进程都有一个主线程,它需要处理各种琐碎。所以 V8 给它分配了两个好帮手:消息队列和事件循环。

单线程顺序处理任务

void MainThread(){
    int num1 = 1+2; // 任务 1
    int num2 = 20/5; // 任务 2
    int num3 = 7*8; // 任务 3
    print(" 最终计算的值为:%d,%d,%d",num,num2,num3)// 任务 4
}

缺点:无法接收并处理新的任务。

引入循环+事件

//GetInput
// 等待用户从键盘输入一个数字,并返回该输入的数字
int GetInput() {
    int input_number = 0;
    cout<<" 请输入一个数:";
    cin>>input_number;
    return input_number;
}

// 主线程 (Main Thread)
void MainThread() {
    for(; ;) {
        int first_num = GetInput()int second_num = GetInput();
        result_num = first_num + second_num;
        print(" 最终计算的值为:%d",result_num)}
}

缺点:无法处理其他线程(IO 线程)发来的任务。

引入消息队列

  1. 构造队列
class TaskQueue{
  public:
  Task takeTask(); // 取出队列头部的一个任务
  void pushTask(Task task); // 添加一个任务到队列尾部
};
  1. 改造主线程
TaskQueue task_queue;
bool keep_running = true; // 退出标志
void ProcessTask();
void MainThread(){
  for(; ;){
    Task task = task_queue.takeTask();
    ProcessTask(task); // 执行取出的任务
		if(!keep_running) // 如果设置了退出标志,那么直接退出线程循环
		  break; 
  }
}
  1. 添加新任务到消息队列
Task clickTask;
task_queue.pushTask(clickTask)

JS单线程架构

如何处理高优先级任务

比如监听DOM变更,采用同步通知的方式,会影响当前任务的执行效率;如果采用异步方式,又会影响到监控的实时性。从而引入微任务

如何解决单个任务执行过久

通过回调让要执行的 JavaScript 任务滞后执行。