在 React 里,微任务的处理至关重要,它保障了更新和渲染操作能够高效、有序地开展。下面按照优先级顺序介绍 React 中微任务的不同处理方式:
1. 使用 MessageChannel
- 原理:
MessageChannel
能够创建一个消息通道,该通道包含两个端口(port1
和port2
),借助在这两个端口间传递消息,可将回调函数作为微任务添加到微任务队列里。 - 优势:性能出色,能确保微任务的执行顺序,在支持
MessageChannel
的环境下,这是 React 优先采用的方式。 - 实现示例:
if (typeof MessageChannel === 'function') {
const channel = new MessageChannel();
const port = channel.port2;
const callbacks = [];
channel.port1.onmessage = function () {
const callback = callbacks.shift();
if (callback) {
try {
callback();
} catch (error) {
console.error(error);
}
}
};
const scheduleMicrotask = function (callback) {
callbacks.push(callback);
port.postMessage(null);
};
}
2. 使用 Promise
- 原理:
Promise
是 JavaScript 里常用的异步编程机制,其.then()
方法中的回调函数会作为微任务被添加到微任务队列中。当MessageChannel
不可用时,React 会使用Promise
来实现微任务调度。 - 优势:兼容性良好,在现代 JavaScript 环境中得到广泛支持。
- 实现示例:
if (typeof Promise === 'function' && typeof MessageChannel!== 'function') {
const scheduleMicrotask = function (callback) {
Promise.resolve().then(callback);
};
}
3. 同步执行(降级策略)
- 原理:若环境既不支持
MessageChannel
也不支持Promise
,最简单的降级策略是直接同步执行回调函数,也就是任务会马上执行,而非作为微任务在合适的时机执行。 - 劣势:会阻塞主线程,可能致使页面响应迟缓,严重影响用户体验。
- 实现示例:
if (typeof Promise!== 'function' && typeof MessageChannel!== 'function') {
const scheduleMicrotask = function (callback) {
callback();
};
}
4. 使用宏任务模拟微任务(不推荐的降级策略)
- 原理:可以运用
setTimeout
或setImmediate
(仅在 Node.js 环境)等宏任务来模拟微任务。不过,宏任务的执行时机和微任务不同,可能会引发一些意外状况。 - 劣势:宏任务的执行优先级低于微任务,可能会使一些依赖微任务顺序的逻辑出现问题。
- 实现示例:
if (typeof Promise!== 'function' && typeof MessageChannel!== 'function' && typeof setTimeout === 'function') {
const scheduleMicrotask = function (callback) {
setTimeout(callback, 0);
};
}
综上所述,React 会依据环境的支持状况,按照从优到劣的顺序选择微任务的处理方式,以尽可能确保更新和渲染操作的高效执行。