Web 接口
后台任务 API - 提供了由用户代理自动执行的队列任务的能力
以下是上面代码的实际运作结果。尝试一下,在浏览器的开发人员工具中使用它,并在您自己的代码中使用它。
源代码:
点击运行 »
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style type="text/css"> body { padding: 0; margin: 0; } svg:not(:root) { display: block; } .playable-code { background-color: #f4f7f8; border: none; border-left: 6px solid #558abb; border-width: medium medium medium 6px; color: #4d4e53; height: 100px; width: 90%; padding: 10px 10px 0; } .playable-canvas { border: 1px solid #4d4e53; border-radius: 2px; } .playable-buttons { text-align: right; width: 90%; padding: 5px 10px 5px 26px; } </style> <style type="text/css"> body { font-family: "Open Sans", "Lucida Grande", "Arial", sans-serif; font-size: 16px; } .logBox { margin-top: 16px; width: 400px; height:500px; border-radius: 6px; border: 1px solid black; box-shadow: 4px 4px 2px black; } .logHeader { margin: 0; padding: 0 6px 4px; height: 22px; background-color: lightblue; border-bottom: 1px solid black; border-radius: 6px 6px 0 0; } #log { font: 12px "Courier", monospace; padding: 6px; overflow: auto; overflow-y: scroll; width: 388px; height: 460px; } .container { width: 400px; padding: 6px; border-radius: 6px; border: 1px solid black; box-shadow: 4px 4px 2px black; display: block; overflow: auto; } .label { display: inline-block; } .counter { text-align: right; padding-top: 4px; float: right; } .button { padding-top: 2px; padding-bottom: 4px; width: 100px; display: inline-block; float: left; border: 1px solid black; cursor: pointer; text-align: center; margin-top: 0; color: white; background-color: darkgreen; } #progress { width: 100%; padding-top: 6px; } </style> <title>后台任务 API - 实例 - 代码示例</title> </head> <body> <p> 使用 <code>requestIdleCallback()</code> 方法协同安排的后台任务的演示。 </p> <div class="container"> <div class="label">解码量子丝速子发射...</div> <progress id="progress" value="0"></progress> <div class="button" id="startButton"> 开始 </div> <div class="label counter"> 任务 <span id="currentTaskNumber">0</span> of <span id="totalTaskCount">0</span> </div> </div> <div class="logBox"> <div class="logHeader"> 日志 </div> <div id="log"> </div> </div> <script> let taskList = []; let totalTaskCount = 0; let currentTaskNumber = 0; let taskHandle = null; let totalTaskCountElem = document.getElementById("totalTaskCount"); let currentTaskNumberElem = document.getElementById("currentTaskNumber"); let progressBarElem = document.getElementById("progress"); let startButtonElem = document.getElementById("startButton"); let logElem = document.getElementById("log"); let logFragment = null; let statusRefreshScheduled = false; window.requestIdleCallback = window.requestIdleCallback || function(handler) { let startTime = Date.now(); return setTimeout(function() { handler({ didTimeout: false, timeRemaining: function() { return Math.max(0, 50.0 - (Date.now() - startTime)); } }); }, 1); }; window.cancelIdleCallback = window.cancelIdleCallback || function(id) { clearTimeout(id); }; function enqueueTask(taskHandler, taskData) { taskList.push({ handler: taskHandler, data: taskData }); totalTaskCount++; if (!taskHandle) { taskHandle = requestIdleCallback(runTaskQueue, { timeout: 1000 }); } scheduleStatusRefresh(); } function runTaskQueue(deadline) { while ((deadline.timeRemaining() > 0 || deadline.didTimeout) && taskList.length) { let task = taskList.shift(); currentTaskNumber++; task.handler(task.data); scheduleStatusRefresh(); } if (taskList.length) { taskHandle = requestIdleCallback(runTaskQueue, { timeout: 1000} ); } else { taskHandle = 0; } } function scheduleStatusRefresh() { if (!statusRefreshScheduled) { requestAnimationFrame(updateDisplay); statusRefreshScheduled = true; } } function updateDisplay() { let scrolledToEnd = logElem.scrollHeight - logElem.clientHeight <= logElem.scrollTop + 1; if (totalTaskCount) { if (progressBarElem.max != totalTaskCount) { totalTaskCountElem.textContent = totalTaskCount; progressBarElem.max = totalTaskCount; } if (progressBarElem.value != currentTaskNumber) { currentTaskNumberElem.textContent = currentTaskNumber; progressBarElem.value = currentTaskNumber; } } if (logFragment) { logElem.appendChild(logFragment); logFragment = null; } if (scrolledToEnd) { logElem.scrollTop = logElem.scrollHeight - logElem.clientHeight; } statusRefreshScheduled = false; } function log(text) { if (!logFragment) { logFragment = document.createDocumentFragment(); } const el = document.createElement("div"); el.textContent = text; logFragment.appendChild(el); } function logTaskHandler(data) { log("运行任务 #" + currentTaskNumber); for (i=0; i<data.count; i+=1) { log((i+1).toString() + ". " + data.text); } } function getRandomIntInclusive(min, max) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1)) + min; } function decodeTechnoStuff() { totalTaskCount = 0; currentTaskNumber = 0; updateDisplay(); let n = getRandomIntInclusive(100, 200); for (i=0; i<n; i++) { let taskData = { count: getRandomIntInclusive(75, 150), text: "该文本来自任务编号:" + (i+1).toString() + " / " + n }; enqueueTask(logTaskHandler, taskData); } } document.getElementById("startButton").addEventListener("click", decodeTechnoStuff, false); </script> </body> </html>
运行结果:
点击运行 »