确保函数只会被调用一次。
产生一个闭包
,在闭包
中保存一个标记变量called
用于判断目标函数
是否已经调用过。
通过该标记变量确保函数只会被调用一次。
为了允许函数可以改变其this
指向(例如在事件监听回调中),这里使用function
关键字声明返回的函数,并且为需要调用的函数绑定this
指向。
使用扩展运算符...
使函数可以接受任意数量的参数。
const once = fn => {
let called = false;
return function(...args) {
if (called) return;
called = true;
return fn.apply(this, args);
};
};
const startApp = function(event) {
// document.body, MouseEvent
console.log(this, event);
};
// 点击事件触发时startApp只会执行一次
document.body.addEventListener('click', once(startApp));
在React
源码中,同样利用了闭包
保存标记变量的特性来标记目标函数
的执行优先级
.
function runWithPriority(priorityLevel, eventHandler) {
var previousPriorityLevel = currentPriorityLevel;
currentPriorityLevel = priorityLevel;
try {
return eventHandler();
} finally {
currentPriorityLevel = previousPriorityLevel;
}
}
runWithPriority
方法接收一个优先级变量priorityLevel
和一个回调函数eventHandler
。
在eventHandler
执行前先将当前执行上下文的currentPriorityLevel
保存在previousPriorityLevel
。
接下来将currentPriorityLevel
赋值为传入的priorityLevel
,并在eventHandler
调用结束后恢复currentPriorityLevel
为previousPriorityLevel
。
这样,在eventHandler
调用栈中获取的currentPriorityLevel
始终为runWithPriority
的传参priorityLevel
。
通过这样的方式,React
得以区分不同交互事件产生的更新
的优先级
。