setTimeout 和 setInterval 會(huì)被瀏覽器自己的系統(tǒng)處理進(jìn)行降速節(jié)約資源. 那么如何避免這個(gè)呢, 就用web worker來發(fā)布定時(shí)任務(wù), 就可以避免瀏覽器自己的行為.
- 新建一個(gè)js文件, 放入worker工作本體 (自己格式化一下)
// Build a worker from an anonymous function body
const blobURL = URL.createObjectURL(
new Blob(
[
'(',
function() {
const intervalIds = {};
// 監(jiān)聽message 開始執(zhí)行定時(shí)器或者銷毀
self.onmessage = function onMsgFunc(e) {
switch (e.data.command) {
case 'interval:start': // 開啟定時(shí)器
const intervalId = setInterval(function() {
postMessage({
message: 'interval:tick',
id: e.data.id,
});
}, e.data.interval);
postMessage({
message: 'interval:started',
id: e.data.id,
});
intervalIds[e.data.id] = intervalId;
break;
case 'interval:clear': // 銷毀
clearInterval(intervalIds[e.data.id]);
postMessage({
message: 'interval:cleared',
id: e.data.id,
});
delete intervalIds[e.data.id];
break;
}
};
}.toString(),
')()',
],
{ type: 'application/javascript' },
),
);
const worker = new Worker(blobURL);
URL.revokeObjectURL(blobURL);
const workerTimer = {
id: 0,
callbacks: {},
setInterval: function(cb, interval, context) {
this.id++;
const id = this.id;
this.callbacks[id] = { fn: cb, context: context };
worker.postMessage({
command: 'interval:start',
interval: interval,
id: id,
});
return id;
},
setTimeout: function(cb, timeout, context) {
this.id++;
const id = this.id;
this.callbacks[id] = { fn: cb, context: context };
worker.postMessage({ command: 'timeout:start', timeout: timeout, id: id });
return id;
},
// 監(jiān)聽worker 里面的定時(shí)器發(fā)送的message 然后執(zhí)行回調(diào)函數(shù)
onMessage: function(e) {
switch (e.data.message) {
case 'interval:tick':
case 'timeout:tick': {
const callbackItem = this.callbacks[e.data.id];
if (callbackItem && callbackItem.fn)
callbackItem.fn.apply(callbackItem.context);
break;
}
case 'interval:cleared':
case 'timeout:cleared':
delete this.callbacks[e.data.id];
break;
}
},
// 往worker里面發(fā)送銷毀指令
clearInterval: function(id) {
worker.postMessage({ command: 'interval:clear', id: id });
},
clearTimeout: function(id) {
worker.postMessage({ command: 'timeout:clear', id: id });
},
};
worker.onmessage = workerTimer.onMessage.bind(workerTimer);
export default workerTimer;
- 在調(diào)用的地方
import workerTimer from '你的路徑’
// 開啟
const currentInterval = workerTimer.setInterval(() => {
fetchCurrentTableNameUser();
}, 30000);
// 注銷
workerTimer.clearInterval(currentInterval);
大功告成.