惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Cloudflare Blog
Microsoft Security Blog
Microsoft Security Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
L
LangChain Blog
W
WeLiveSecurity
P
Proofpoint News Feed
月光博客
月光博客
NISL@THU
NISL@THU
L
LINUX DO - 最新话题
Webroot Blog
Webroot Blog
T
Threatpost
Y
Y Combinator Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Threat Research - Cisco Blogs
Vercel News
Vercel News
Jina AI
Jina AI
阮一峰的网络日志
阮一峰的网络日志
S
Schneier on Security
J
Java Code Geeks
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
小众软件
小众软件
MyScale Blog
MyScale Blog
N
News and Events Feed by Topic
Stack Overflow Blog
Stack Overflow Blog
有赞技术团队
有赞技术团队
The Hacker News
The Hacker News
Schneier on Security
Schneier on Security
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Help Net Security
Help Net Security
Recent Announcements
Recent Announcements
S
Security @ Cisco Blogs
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Securelist
T
The Exploit Database - CXSecurity.com
云风的 BLOG
云风的 BLOG
C
Cisco Blogs
雷峰网
雷峰网
量子位
Google DeepMind News
Google DeepMind News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Spread Privacy
Spread Privacy
L
Lohrmann on Cybersecurity
I
Intezer
T
The Blog of Author Tim Ferriss
G
GRAHAM CLULEY
D
DataBreaches.Net
V
Vulnerabilities – Threatpost
P
Privacy & Cybersecurity Law Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
罗磊的独立博客

Coding Your Life

lib库开发的一款PDF处理小工具 | Coding Your Life mirror-cli | Coding Your Life 最长递增子序列算法 | Coding Your Life webpack5 模块联邦技术 | Coding Your Life webpack基础配置详解 | Coding Your Life canvas实现代码雨效果 | Coding Your Life vue3 和 react 虚拟dom | Coding Your Life ES6中Reflect对象与Proxy结合实现代理和响应式编程 | Coding Your Life 前端技术分享MediaRecord实现运动相机 | Coding Your Life react基础概念 | Coding Your Life 微信小程序使用canvas创建像素头像 | Coding Your Life 前端基础概念 | Coding Your Life 中高级前端须注意的40条移动端H5坑位指南 | Coding Your Life native-code-push 热更新配置 | Coding Your Life Git 常用命令速查表 | Coding Your Life push-server 热更新常用命令速查表 | Coding Your Life 高效的js片段 | Coding Your Life
使用MessageChannel模拟React优先级执行队列 | Coding Your Life
Sir_Liu · 2025-05-23 · via Coding Your Life

前言

MessageChannelHTML5window 对象提供的一个用于跨线程通信的 API,它允许我们在不同的浏览上下文(如主线程与 Worker 线程)之间传递数据。React 利用了 MessageChannel 来实现优先级任务调度,模拟异步任务队列。

以下是关于 MessageChannel 的关键点:

MessageChannel 创建两个端口 (port1, port2),它们可以互相发送消息。
在 React 的调度器中,使用 MessageChannel 将低优先级任务延迟执行,而高优先级任务可以中断低优先级任务。
通过 port.postMessage() 将任务加入队列,通过监听 message 事件来触发任务执行。
相比 setTimeoutMessageChannel 提供了更细粒度的控制,并且在浏览器中具有更高的优先级。
示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

enum ScheduleType {
event = 1000,
timeout = 2000,
}
type ScheduleItem = {
time: number,
callback: Function
}

class SimpleSchedule {
private queue: Array<any> = [];
private port1: MessagePort;
private port2: MessagePort;
private isRunning: boolean = false;
constructor() {

const channel = new MessageChannel();
this.port1 = channel.port1;
this.port2 = channel.port2;

this.onSchedule = this.onSchedule.bind(this);
this.port1.onmessage = this.onSchedule;
}
onSchedule(){
console.log('开始执行了')
this.queueLoop();
}
dispatchMsg(){
this.port2.postMessage(null);
}
schedule(fn: Function, scheduleType: ScheduleType){
const time = performance.now() + scheduleType;
this.push({callback: fn, time });
if(!this.isRunning){
this.isRunning = true;
this.dispatchMsg();
}

}
push(schedule: ScheduleItem){
this.queue.push(schedule);
this.queue.sort((a,b)=>a.time - b.time);
}
pop(){
return this.queue.shift()
}
queueLoop(){
let schedule = this.pop();
while(schedule){
schedule.callback();
schedule = this.pop();
}
this.isRunning = false;
}
}
const simpleSchedule = new SimpleSchedule();

simpleSchedule.schedule(()=>{
console.log('schedule 1');
},ScheduleType.timeout);

simpleSchedule.schedule(()=>{
console.log('schedule 2');
},ScheduleType.event);

开始执行了
schedule 2
schedule 1

上述代码中,SimpleSchedule类是一个简单的调度器,用于管理多个任务。它使用一个队列来保存任务,并使用一个isRunning属性来指示当前是否正在执行任务。

ts文件可以直接用ts-node运行,如果报错TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for...... 请在ts-connfig中添加"ts-node": { "esm": true }

今天的分享就到这了,如有疑问🤔️评论区见