JavaScript计划任务后台运行的方法


Posted in Javascript onDecember 18, 2015

即使忘了 JavaScript 的一切知识,也不会忘记:它是阻塞的。

想象一下,你的浏览器里住着一个魔法小精灵,负责浏览器的正常运转。不论渲染 HTML,响应菜单命令,屏幕渲染,处理鼠标点击,或者执行 JavaScript 函数,所有事情都归一个小精灵处理。它哪忙得过来,一次只能处理一件事情。如果同时丢给它一堆任务,它会列一个长长的待办列表,按顺序完成它们。

人们常常希望初始化组件和事件处理的 JavaScript 可以尽快被执行。可是,有些不太重要的后台任务不会直接影响用户体验,比如:

记录统计数据

发送数据到社交网络(或添加‘分享'按钮)

预加载内容

预处理或预渲染 HTML

他们对时序要求不严格,但是为了让页面仍然响应,直到用户滚动页面或者与内容交互时才被执行。

选择之一是 Web Workers ,它可以在独立的线程同时执行代码。用于预加载和预处理再好不过,但是你没有权限直接访问或更新 DOM。你可以在自己的代码中避开这点,但是无法保证第三方脚本比如 Google Analytics 永远不需要这个。

另一个选择是setTimeout,比如setTimeout(doSomething, 1);。一旦其它的立即执行任务执行完毕,浏览器将执行doSomething()函数。实际上,它被放到了待办列表的底部。不幸的是,函数将被调用,而不顾处理需求。

#requestIdleCallback

requestIdleCallback 是新API,当浏览器稍作喘息的时候,用来执行不太重要的后台计划任务。 难免让人想起 requestAnimationFrame ,在下次重绘之前,执行函数更新动画。 想了解更多戳这里: 使用 requestAnimationFrame 做简单的动画 。

requestIdleCallback特性监测:

if ('requestIdleCallback' in window) {
 // requestIdleCallback supported
 requestIdleCallback(backgroundTask);
}
else {
 // no support - do something else
 setTimeout(backgroundTask1, 1);
 setTimeout(backgroundTask2, 1);
 setTimeout(backgroundTask3, 1);
}

也可以指定配置参数对象,比如 timeout,

requestIdleCallback(backgroundTask, { timeout: 3000; });

确保函数在3秒之内调用,不管浏览器是否空闲。

deadline对象传入以下参数时,requestIdleCallback仅执行一次回调:

didTimeout—— 如果可选的 timeout 触发,则设置为 true
timeRemaining()—— 函数返回执行任务剩余的毫秒数
timeRemaining()最多分配50ms用于任务的执行,超过这个限制,也不会停止任务,但是,最好重新调用requestIdleCallback安排进一步的处理。

我们来创建一个简单的例子,让几个任务按序执行。任务的函数引用储存在数组中:

//待执行的函数数组
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);
 }
}

#一次 requestIdleCallback 之间不应该做什么?

Paul Lewis 在 他的文章 中提到,一次 requestIdleCallback 执行的任务应该切成小块。它不适用于不可预知时间的情况(比如操作 DOM,使用 requestAnimationFrame 回调更好些)。resolving(或者 rejecting)Promises 时也要谨慎,即使没有更多的剩余时间,空闲回调完成之后,回调函数也将立即执行。

#requestIdleCallback 浏览器支持情况

requestIdleCallback是试验性特性,规范仍不稳定,碰到 API 变更时不足为奇。Chrome 47 已支持… 2015年结束前应该可用了。Opera 应该会紧跟其后。Microsoft 和 Mozilla 都在考虑 API 是否应该支持 Promises 。Apple 像往常一样不鸟。

Paul Lewis(上文提到的)写了一个简单的 requestIdleCallback shim ,它可以模拟浏览器的空闲监测行为,但不是一个 polyfill( shim 和 polyfill 的区别 )。

requestIdleCallback shim代码如下:

/*!
 * 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设置→安全设置→本地计算机策略→安全选项”;双击右侧的“账户:使用空白密码的本地账户只允许进行控制台登录”项,在弹出对话框中选择“已禁用”。

Javascript 相关文章推荐
如何做到打开一个页面,过几分钟自动转到另一页面
Apr 20 Javascript
JQuery.ajax传递中文参数的解决方法 推荐
Mar 28 Javascript
JavaScript call apply使用 JavaScript对象的方法绑定到DOM事件后this指向问题
Sep 28 Javascript
jquery实现加载等待效果示例
Sep 25 Javascript
JavaScript中document.forms[0]与getElementByName区别
Jan 21 Javascript
javascript实现选中复选框后相关输入框变灰不可用的方法
Aug 11 Javascript
jQuery+CSS实现的网页二级下滑菜单效果
Aug 25 Javascript
在javascript中随机数 math random如何生成指定范围数值的随机数
Oct 21 Javascript
在vue项目中引入高德地图及其UI组件的方法
Sep 04 Javascript
vue-cli 使用vue-bus来全局控制的实例讲解
Sep 15 Javascript
微信小程序自定义组件传值 页面和组件相互传数据操作示例
May 05 Javascript
JavaScript用document.write()输出换行的示例代码
Nov 26 Javascript
JavaScript jQuery 中定义数组与操作及jquery数组操作
Dec 18 #Javascript
原生js实现移动端瀑布流式代码示例
Dec 18 #Javascript
jQuery Validate表单验证入门学习
Dec 18 #Javascript
jQuery定义插件的方法
Dec 18 #Javascript
jQuery Validate插件实现表单强大的验证功能
Dec 18 #Javascript
jquery实现二级导航下拉菜单效果
Dec 18 #Javascript
学习jQuey中的return false
Dec 18 #Javascript
You might like
elgg 获取文件图标地址的方法
2010/03/20 PHP
兼容性最强的PHP生成缩略图的函数代码(修改版)
2011/01/18 PHP
hadoop中一些常用的命令介绍
2013/06/19 PHP
PHP中file_exists使用中遇到的问题小结
2016/04/05 PHP
PHP给源代码加密的几种方法汇总(推荐)
2018/02/06 PHP
PHP 实现手机端APP支付宝支付功能
2018/06/07 PHP
PHP实现带进度条的Ajax文件上传功能示例
2019/07/02 PHP
JAVASCRIPT车架号识别/验证函数代码 汽车车架号验证程序
2012/01/08 Javascript
用JQuery在网页中实现分隔条功能的代码
2012/08/09 Javascript
JavaScript四种调用模式和this示例介绍
2014/01/02 Javascript
jQuery基于扩展实现的倒计时效果
2016/05/14 Javascript
使用HTML5+Boostrap打造简单的音乐播放器
2016/08/05 Javascript
Cropper.js 实现裁剪图片并上传(PC端)
2017/08/20 Javascript
jQuery实现文件编码成base64并通过AJAX上传的方法
2018/04/12 jQuery
vue click.stop阻止点击事件继续传播的方法
2018/09/04 Javascript
ES6 async、await的基本使用方法示例
2020/06/06 Javascript
Python PyQt5标准对话框用法示例
2017/08/23 Python
python3+mysql查询数据并通过邮件群发excel附件
2018/02/24 Python
python获取程序执行文件路径的方法(推荐)
2018/04/26 Python
Python基于mysql实现学生管理系统
2019/02/21 Python
python PyAutoGUI 模拟鼠标键盘操作和截屏功能
2019/08/04 Python
解决django同步数据库的时候app models表没有成功创建的问题
2019/08/09 Python
Python如何实现的二分查找算法
2020/05/27 Python
Python基础教程(一)——Windows搭建开发Python开发环境
2020/07/20 Python
CSS3 制作绽放的莲花采用效果叠加实现
2013/01/31 HTML / CSS
HTML5 video播放器全屏(fullScreen)方法实例
2015/04/24 HTML / CSS
英语专业个人求职自荐信
2013/09/21 职场文书
幼教个人求职信范文
2013/12/02 职场文书
大学活动邀请函
2014/01/28 职场文书
一年级语文教学反思
2014/02/13 职场文书
优秀会计求职信
2014/07/04 职场文书
信用卡结清证明怎么写
2014/09/13 职场文书
反对形式主义、官僚主义、享乐主义和奢靡之风整改措施
2014/09/17 职场文书
第二批党的群众路线教育实践活动总结报告
2014/10/30 职场文书
2015新生加入学生会自荐书
2015/03/24 职场文书
PYTHON InceptionV3模型的复现详解
2022/05/06 Python