Home > Article > Web Front-end > How to run JavaScript scheduled tasks in the background_javascript tips
Even if you forget everything you know about JavaScript, you will never forget: it is blocking.
Imagine that there is a magic elf living in your browser, responsible for the normal operation of the browser. Whether it's rendering HTML, responding to menu commands, rendering the screen, handling mouse clicks, or executing JavaScript functions, everything is handled by a single elf. It's so busy that it can only handle one thing at a time. If you throw a bunch of tasks at it at the same time, it will make a long to-do list and complete them in order.
People often want the JavaScript that initializes components and event handlers to be executed as quickly as possible. However, some less important background tasks do not directly affect the user experience, such as:
Record statistics
Send data to social networks (or add 'share' button)
Preloaded content
Preprocess or prerender HTML
They are not timing strict, but in order for the page to remain responsive, they are not executed until the user scrolls the page or interacts with the content.
One option is Web Workers, which can execute code simultaneously in independent threads. Great for preloading and preprocessing, but you don't have direct access to or update the DOM. You can get around this in your own code, but there's no guarantee that third-party scripts like Google Analytics will never need this.
Another option is setTimeout, such as setTimeout(doSomething, 1);. Once other immediate tasks have been executed, the browser will execute the doSomething() function. In fact, it was pushed to the bottom of the to-do list. Unfortunately, the function will be called regardless of processing needs.
#requestIdleCallback
requestIdleCallback is a new API, used to perform less important background scheduled tasks when the browser takes a breather. It is inevitably reminiscent of requestAnimationFrame, which executes the function to update the animation before the next redraw. If you want to know more, click here: Use requestAnimationFrame to make simple animations.
requestIdleCallback feature monitoring:
if ('requestIdleCallback' in window) { // requestIdleCallback supported requestIdleCallback(backgroundTask); } else { // no support - do something else setTimeout(backgroundTask1, 1); setTimeout(backgroundTask2, 1); setTimeout(backgroundTask3, 1); }
You can also specify configuration parameter objects, such as timeout,
requestIdleCallback(backgroundTask, { timeout: 3000; });
Ensure that the function is called within 3 seconds, regardless of whether the browser is idle.
When the deadline object passes in the following parameters, requestIdleCallback only executes the callback once:
didTimeout - Set to true if optional timeout fires
timeRemaining()—— Function returns the number of milliseconds remaining to execute the task
timeRemaining() allocates up to 50ms for task execution. If this limit is exceeded, the task will not be stopped. However, it is best to re-call requestIdleCallback to arrange further processing.
Let’s create a simple example to execute several tasks in sequence. The function reference of the task is stored in the array:
//待执行的函数数组 var task = [ background1, background2, background3 ]; if ('requestIdleCallback' in window) { //支持 requestIdleCallback requestIdleCallback(backgroundTask); } else { //不支持 —— 立刻执行所有任务 while (task.length) { setTimeout(task.shift(), 1); } } //requestIdleCallback 回调函数 function backgroundTask(deadline) { //如果存在,执行下一个任务 while (deadline.timeRemaining() > 0 && task.length > 0) { task.shift()(); } //需要的话,安排进一步任务 if (task.length > 0) { requestIdleCallback(backgroundTask); } }
#What should not be done between requestIdleCallback?
Paul Lewis mentioned in his article that the tasks performed by a requestIdleCallback should be cut into small pieces. It is not suitable for unpredictable time situations (such as operating DOM, it is better to use requestAnimationFrame callback). Also be careful when resolving (or rejecting) Promises, the callback function will be executed immediately after the idle callback completes, even if there is no more time left.
#requestIdleCallback Browser support
requestIdleCallback is an experimental feature, the specification is still unstable, and it is not surprising to encounter API changes. Chrome 47 is supported...should be available before the end of 2015. Opera should follow suit. Both Microsoft and Mozilla are considering whether APIs should support Promises. Apple, as usual, is being pessimistic.
Paul Lewis (mentioned above) wrote a simple requestIdleCallback shim, which can simulate the browser's idle monitoring behavior, but is not a polyfill (the difference between shim and polyfill).
requestIdleCallback shim code is as follows:
/*! * Copyright Google Inc. All rights reserved. * * Licensed under the Apache License, Version . (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing * permissions and limitations under the License. */ /* * @see https://developers.google.com/web/updates///using-requestidlecallback */ window.requestIdleCallback = window.requestIdleCallback || function (cb) { var start = Date.now(); return setTimeout(function () { cb({ didTimeout: false, timeRemaining: function () { return Math.max(, - (Date.now() - start)); } }); }, ); } window.cancelIdleCallback = window.cancelIdleCallback || function (id) { clearTimeout(id); }
ps: 如何執行排程任務
1、運行 GPEDIT.MSC
2、選擇電腦設定
--- Windows 設定
--- 安全設定
--- 本地策略
--- 使用者權利指派
雙擊右邊的 從網路存取此電腦
把需要的使用者名稱加到列表。
3、 --- 安全設定
---安全選擇
開啟允許伺服器操作員規劃任務
4、-----本地策略
--- 作為批次作業登入
把需要的使用者名稱加到清單上。
5、-----本地策略
--- 允許電腦和使用者被信任以便於委託
把需要的使用者名稱加到列表。
最好是administrator用戶。
如果任務計畫無法啟動,提示代碼:0X80041315
解決方法:這有兩種可能,一是系統中的“Task Scheduler”服務沒有啟動,你可在運行中鍵入“services.msc”,查看“Task Scheduler”服務是否被設定成了“已停用”,若是,只要雙擊它將啟動類型改為“自動”,重新設定一個計劃任務就可以執行了。
如果你目前帳號設定了自動登錄,而其登入密碼又為空,也有可能導致任務計畫不能準時執行,在XP專業版中,需要執行「gpedit.msc」來編輯群組原則:展開「計算機設定→Windows設定→安全設定→本機電腦原則→安全性選項」;雙擊右側的「帳戶:使用空白密碼的本機帳號只允許進行控制台登入」項,在彈出對話方塊中選擇「已停用」。