setTimeout
setTimeout用于在指定的时间后将函数加入任务队列。它返回一个timeoutID,可以用来取消这个计时器。
const timeoutID = setTimeout(function() {
// 任务代码
}, 2000); // 2秒后执行
// 取消计时器
clearTimeout(timeoutID);
setInterval
setInterval: setInterval用于每隔一定时间间隔将函数加入任务队列。它同样返回一个intervalID,可以用来取消这个计时器。
setInterval在每次把任务push到任务队列前,都要进行一下判断(看上次的任务是否仍在队列中,进行是否加入)
const intervalID = setInterval(function() {
// 任务代码
}, 1000); // 每隔1秒执行一次
// 取消计时器
clearInterval(intervalID);
requestAnimationFrame
requestAnimationFrame: requestAnimationFrame中函数在浏览器渲染每一帧都进行触发
浏览器的重绘时间相关
function animate() {
// 动画逻辑
}
requestAnimationFrame(animate);
setImmediate(已废弃)
setImmediate: setImmediate的功能类似于setTimeout,但是它会在当前事件结束后立即执行回调函数,而不是等待指定的时间。
const immediateID = setImmediate(function() {
// 任务代码
});
// 取消立即执行
clearImmediate(immediateID);
这四个方法的应用
requestAnimationFrame:
- 需要频繁触发
setTimeout:
- 仅调用一次。
setInterval:
- 用于创建重复执行的计时器、轮询和非重要操作。
setImmediate:
- 在
事件完成之后立即执行某些清理工作
const fs = require('fs');
fs.readFile('example.txt', (err, data) => {
if (err) throw err;
console.log('File read');
setImmediate(() => {
console.log('Cleanup work done');
});
});
setImmediate在 Vue Nexttick与 React 调度器的使用
nextTick
2.5版本,Vue引入MessageChannel,nextTick的实现优先使用setImmediate,平台不支持则使用MessageChannel,再不支持才使用Promise,最后用setTimeout兜底。
不过到了2.6版本以后,nextTick又改回原来的Promise实现。
if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
timerFunc = () => {
setImmediate(nextTickHandler)
}
} else if (typeof MessageChannel !== 'undefined' && (
isNative(MessageChannel) ||
MessageChannel.toString() === '[object MessageChannelConstructor]'
)) {
const channel = new MessageChannel()
const port = channel.port2
channel.port1.onmessage = nextTickHandler
timerFunc = () => {
port.postMessage(1)
}
} else
if (typeof Promise !== 'undefined' && isNative(Promise)) {
const p = Promise.resolve()
timerFunc = () => {
p.then(nextTickHandler)
}
} else {
timerFunc = () => {
setTimeout(nextTickHandler, 0)
}
}
React 调度器
let schedulePerformWorkUntilDeadline;
if (typeof localSetImmediate === 'function') {
schedulePerformWorkUntilDeadline = () => {
localSetImmediate(performWorkUntilDeadline);
};
} else if (typeof MessageChannel !== 'undefined') {
// DOM and Worker environments.
// We prefer MessageChannel because of the 4ms setTimeout clamping.
const channel = new MessageChannel();
const port = channel.port2;
channel.port1.onmessage = performWorkUntilDeadline;
schedulePerformWorkUntilDeadline = () => {
port.postMessage(null);
};
} else {
// We should only fallback here in non-browser environments.
schedulePerformWorkUntilDeadline = () => {
localSetTimeout(performWorkUntilDeadline, 0);
};
}
setTimeout 实现 setInterval
setInterval在每次把任务push到任务队列前,都要进行一下判断(看上次的任务是否仍在队列中,进行是否加入)
const _setInterval = (callBack, time) => {
let timeId= 0
const fn = () => {
callBack();
timeId = setTimeout(fn, time);
}
timeId = setTimeout(fn, time);
return timeId
}
let a=_setInterval(()=>console.log(1),1000)
clearTimeout(a)