事件循环
浏览器多进程架构,其中渲染进程负责渲染页面。每个渲染进程都有一个主线程,它需要处理各种琐碎。所以 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 线程)发来的任务。
引入消息队列
- 构造队列
class TaskQueue{
public:
Task takeTask(); // 取出队列头部的一个任务
void pushTask(Task task); // 添加一个任务到队列尾部
};
- 改造主线程
TaskQueue task_queue;
bool keep_running = true; // 退出标志
void ProcessTask();
void MainThread(){
for(; ;){
Task task = task_queue.takeTask();
ProcessTask(task); // 执行取出的任务
if(!keep_running) // 如果设置了退出标志,那么直接退出线程循环
break;
}
}
- 添加新任务到消息队列
Task clickTask;
task_queue.pushTask(clickTask)
JS单线程架构
如何处理高优先级任务
比如监听DOM变更,采用同步通知的方式,会影响当前任务的执行效率;如果采用异步方式,又会影响到监控的实时性。从而引入微任务。
如何解决单个任务执行过久
通过回调让要执行的 JavaScript 任务滞后执行。