定时器学习:利用定时器分解耗时任务案例

对于执行时间过长的脚本,有的浏览器会弹出警告,说页面无响应。有的浏览器会直接终止脚本。总而言之,浏览器不希望某一个代码块长时间处于运行状态,因为js是单线程的。一个代码块长时间运行,将会导致其他任何任务都必须等待。从用户体验上来说,很有可能发生页面渲染卡顿或者点击事件无响应的状态。 如果一段脚本的运行时间超过5秒,有些浏览器(比如Firefox和Opera)将弹出一个对话框警告用户该脚本“无法响应”。而其他浏览器,比如iPhone上的浏览器,将默认终止运行时间超过5秒钟的脚本。–《JavaScript忍者秘籍》 JavaScript忍者秘籍里有个很好的比喻:页面上发生的各种事情就好像一群人在讨论事情,如果有个人一直在说个不停,其他人肯定不乐意。我们希望有个裁判,定时的切换其他人来说话。 Js利用定时器来分解任务,关键点有两个。 按什么维度去分解任务 任务的现场保存与现场恢复 1. 例子 要求:动态创建一个表格,一共10000行,每行10个单元格 1.1. 一次性创建 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <table> <tbody></tbody> </table> <script type="text/javascript"> var tbody = document.getElementsByTagName('tbody')[0]; var allLines = 10000; // 每次渲染的行数 console.time('wd'); for(var i=0; i<allLines; i++){ var tr = document.createElement('tr'); for(var j=0; j<10; j++){ var td = document.createElement('td'); td.appendChild(document.createTextNode(i+','+j)); tr.appendChild(td); } tbody.appendChild(tr); } console.timeEnd('wd'); </script> </body> </html> 总共耗时180ms, 浏览器已经给出警告![Violation] 'setTimeout' handler took 53ms。 1.2. 分批次动态创建 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <table> <tbody></tbody> </table> <script type="text/javascript"> var tbody = document....

2018-02-08 14:09:54 · 1 min · Eddie Wang

关于JavaScropt函数式编程,我多么希望能早点看到这本书

我父亲以前跟我说过,有些事物在你得到之前是无足轻重的,得到之后就不可或缺了。微波炉是这样,智能手机是这样,互联网也是这样——老人们在没有互联网的时候过得也很充实。对我来说,函数的柯里化(curry)也是这样。 然后我继续看了这本书的中文版。有些醍醐灌顶的感觉。 随之在github搜了一下。 我想,即使付费,我也愿意看。 中文版地址:https://www.gitbook.com/book/llh911001/mostly-adequate-guide-chinese/details github原文地址:https://github.com/MostlyAdequate/mostly-adequate-guide 1. 后记 其实我是想学点函数柯里化的东西,然后用谷歌搜索了一下。第一个结果就是这本书。非常感谢谷歌搜索,如果我用百度,可能就没有缘分遇到这本书了。

2018-02-08 14:06:22 · 1 min · Eddie Wang

终于找到你!如何将前端console.log的日志保存成文件?

本篇文章来自一个需求,前端websocket会收到各种消息,但是调试的时候,我希望把websoekt推送过来的消息都保存到一个文件里,如果出问题的时候,我可以把这些消息的日志文件提交给后端开发区分析错误。但是在浏览器里,js一般是不能写文件的。鼠标另存为的方法也是不太好,因为会保存所有的console.log的输出。于是,终于找到这个debugout.js。 debugout.js的原理是将所有日志序列化后,保存到一个变量里。当然这个变量不会无限大,因为默认的最大日志限制是2500行,这个是可配置的。另外,debugout.js也支持在localStorage里存储日志的。 1. debugout.js 一般来说,可以使用打开console面板,然后右键save,是可以将console.log输出的信息另存为log文件的。但是这就把所有的日志都包含进来了,如何只保存我想要的日志呢? (调试输出)从您的日志中生成可以搜索,时间戳,下载等的文本文件。 参见下面的一些例子。 Debugout的log()接受任何类型的对象,包括函数。 Debugout不是一个猴子补丁,而是一个单独的记录类,你使用而不是控制台。 调试的一些亮点: 在运行时或任何时间获取整个日志或尾部 搜索并切片日志 更好地了解可选时间戳的使用模式 在一个地方切换实时日志记录(console.log) 可选地将输出存储在window.localStorage中,并在每个会话中持续添加到同一个日志 可选地,将日志上限为X个最新行以限制内存消耗 下图是使用downloadLog方法下载的日志文件。 官方提供的demo示例,欢迎试玩。http://inorganik.github.io/debugout.js/ 2. 使用 在脚本顶部的全局命名空间中创建一个新的调试对象,并使用debugout的日志方法替换所有控制台日志方法: var bugout = new debugout(); // instead of console.log('some object or string') bugout.log('some object or string'); 3. API log() -像console.log(), 但是会自动存储 getLog() - 返回所有日志 tail(numLines) - 返回尾部执行行日志,默认100行 search(string) - 搜索日志 getSlice(start, numLines) - 日志切割 downloadLog() - 下载日志 clear() - 清空日志 determineType() - 一个更细粒度的typeof为您提供方便 4. 可选配置 ··· // log in real time (forwards to console....

2018-02-08 13:56:40 · 1 min · Eddie Wang

如何浏览器里调试iframe里层的代码?

之前一直非常痛苦,在iframe外层根本获取不了里面的信息,后来使用了postMessage用传递消息来实现,但是用起来还是非常不方便。 其实浏览器本身是可以选择不同的iframe的执行环境的。例如有个变量是在iframe里面定义的,你只需要切换到这个iframe的执行环境,你就可以随意操作这个环境的任何变量了。 这个小技巧,对于调试非常有用,但是我直到今天才发现。 1. Chrome 这个小箭头可以让你选择不同的iframe的执行环境,可以切换到你的iframe环境里。 2. IE 如图所示是ie11的dev tool点击下来箭头,也可以选择不同的iframe执行环境。 3. 其他浏览器 其他浏览器可以自行摸索一下。。。(G_H)

2018-02-08 13:53:48 · 1 min · Eddie Wang

Audio 如果你愿意一层一层剥开我的心

我觉得DOM就好像是元素周期表里的元素,JS就好像是实验器材,通过各种化学反应,产生各种魔术。 1. Audio 通过打开谷歌浏览器的dev tools -> Settings -> Elements -> Show user agent shadow DOM, 你可以看到其实Audio标签也是由常用的 input标签和div等标签合成的。 2. 基本用法 1 <audio src="http://65.ierge.cn/12/186/372266.mp3"> Your browser does not support the audio element. </audio> <br> 2 <audio src="http://65.ierge.cn/12/186/372266.mp3" controls="controls"> Your browser does not support the audio element. </audio> <br> // controlsList属性目前只支持 chrome 58+ 3 <audio src="http://65.ierge.cn/12/186/372266.mp3" controls="controls" controlsList="nodownload"> Your browser does not support the audio element. </audio> <br> 4 <audio controls="controls"> <source src="http://65....

2018-02-08 09:44:01 · 2 min · Eddie Wang

可能被遗漏的https与http的知识点

1. HTTPS域向HTTP域发送请求会被浏览器直接拒绝,HTTP向HTTPS则不会 例如在github pages页面,这是一个https页面,如果在这个页面向http发送请求,那么会直接被浏览器拒绝,并在控制台输出下面的报错信息。 jquery-1.11.3.min.js:5 Mixed Content: The page at 'https://wangduanduan.github.io/ddddddd/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://cccccc/log/conf?token=welljoint'. This request has been blocked; the content must be served over HTTPS. 如果你在做第三方集成的系统,如果他们是在浏览器中直接调用你提供的接口,那么最好你使用https协议,这样无论对方是https还是http都可以访问。(相信我,这个很重要,我曾经经历过上线后遇到这个问题,然后连夜申请证书,把http升级到https的痛苦经历) 2. HTTPS的默认端口是443,而不是443 如果443端口已经被其他服务占用了,那么使用其他任何没有被占用的端口都可以用作HTTPS服务,只不过在请求的时候需要加上端口号罢了。 3. 如何快速隐藏一个DOM元素 选中一个元素,然后按h,这时候就会在选中的DOM元素上加上__web-inspector-hide-shortcut__类,这个类会让元素隐藏。谷歌和火狐上都可以,IE上没有试过行不行。

2018-02-08 09:10:59 · 1 min · Eddie Wang

直接在Chrome DevTools调试Node.js

英文好的,直接看原文 https://blog.hospodarets.com/nodejs-debugging-in-chrome-devtools 1. 要求 Node.js 6.3+ Chrome 55+ 2. 操作步骤 1 打开连接 chrome://flags/#enable-devtools-experiments 2 开启开发者工具实验性功能 3 重启浏览器 4 打开 DevTools Setting -> Experiments tab 5 按6次shift后,隐藏的功能会出现,勾选"Node debugging" 3. 运行程序 必须要有 --inspect > node --inspect www Debugger listening on port 9229. Warning: This is an experimental feature and could change at any time. To start debugging, open the following URL in Chrome: chrome-devtools://devtools/remote/serve_file/@60cd6e859b9f557d2312f5bf532f6aec5f284980/inspector.html?experiments=true&v8only=true&ws=localhost:9229/78a884f4-8c2e-459e-93f7-e1cbe87cf5cf 将这个地址粘贴到谷歌浏览器:chrome-devtools://devtools/remote/serve_file/@60cd6e859b9f557d2312f5bf532f6aec5f284980/inspector.html?experiments=true&v8only=true&ws=localhost:9229/78a884f4-8c2e-459e-93f7-e1cbe87cf5cf 程序后端输出的日志也回输出到谷歌浏览器的console里面,同时也可以在Sources里进行断点调试了。

2018-02-07 14:15:43 · 1 min · Eddie Wang

【译】13简单的优秀编码规则(从我15年的经验)

原文地址:https://hackernoon.com/few-simple-rules-for-good-coding-my-15-years-experience-96cb29d4acd9#.ddzpjb80c 嗨,我的工作作为一个程序员超过15年,并使用许多不同的语言,范例,框架和其他狗屎。我想和大家分享我写好代码的规则。 1. 优化VS可读性 去他妈的优化 始终编​​写易于阅读且对开发人员可理解的代码。因为在硬可读代码上花费的时间和资源将远远高于从优化中获得的。 如果你需要进行优化,那么使它像DI的独立模块,具有100%的测试覆盖率,并且不会被触及至少一年。 2. 架构第一 我看到很多人说“我们需要快速做事,我们没有时间做架构”。其中约99%的人因为这样的想法而遇到了大问题。 编写代码而不考虑其架构是没有用的,就像没有实现它们的计划一样,梦想你的愿望。 在编写代码的第一行之前,你应该明白它将要做什么,它将如何使用,模块,服务如何相互工作,它将有什么结构,如何进行测试和调试,以及如何更新。 3. 测试覆盖率 测试是好事,但他们并不总是负担得起,对项目有意义。 当你需要测试: 当你编写模块时,微服务将不会被触及至少一个月。 当你编写开源代码。 当你编写涉及金融渠道的核心代码或代码。 当您有代码更新的同时更新测试的资源。 当你不需要测试时: 当你是一个创业。 当你有小团队和代码更改是快速。 当你编写的脚本,可以简单地通过他们的输出手动测试。 记住,带有严格测试的代码可能比没有测试的代码更有害。 4. 保持简单,极度简单 不要编写复杂的代码。更多更简单,那么更少的错误它可能有和更少的时间来调试它们。代码应该做的只是它需要没有非常多的抽象和其他OOP shit(尤其是涉及java开发人员)+ 20%的东西可能需要在将来以简单的方式更新它。 5. 注释 出现注释说明你的代码不够好。好的代码应该是可以理解的,没有一行注释。但是如何为新开发人员节省时间? - 编写简单的内联文档描述什么和如何方法工作。这将节省很多时间来理解,甚至更多 - 它将给人们更多的机会来提出更好的实施这种方法。并且它将是全球代码文档的良好开端。 6. 硬耦合VS较小耦合 始终尝试使用微服务架构。单片软件可以比微服务软件运行得更快,但只能在一个服务器的上下文中运行。 微服务使您可以不仅在许多服务器上,而且有时甚至在一台机器上(我的意思是过程分发)高效地分发您的软件。 7. 代码审查 代码审查可以是好的,也以是坏的。 您可以组织代码审查,只有当您有开发人员了解95%的代码,谁可以监控所有更新,而不浪费很多时间。在其他情况下,这将是只是耗时,每个人都会讨厌这个。 在这部分有很多问题,所以更深入地描述这一点。 许多人认为代码审查是一个很好的方式教新手,或者工作在不同部分的代码的队友。但是代码审查的主要目标是保持代码质量,而不是教学。让我们想象你的团队制作代码用于控制核反应堆或太空火箭发动机的冷却系统。你在非常硬的逻辑中犯了巨大的错误,然后你给这个代码审查新的家伙。你怎么认为会发生意外的风险? - 我的练习率超过70%。 良好的团队是每个人都有自己的角色,负责确切的工作。如果有人想要理解另一段代码,那么他去一个负责任去问他。你不可能知道一切,更好的优秀的理解小块代码而不是理解所有。 8. 重构没啥用 在我的职业生涯中,我听到很多次“不要担心,我们以后会重构它”。在未来,这会导致大的技术债务或从头开始删除所有的代码和写作。 所以,不要得到一个债务,除非你有钱从头开发你的软件几次。 9. 当你累了或在一个坏的心情不要写代码。 当开发人员厌倦时,他们正在制造2到5倍或者更多的bug。所以工作更多是非常糟糕的做法。这就是为什么越来越多的国家思考6小时工作日,其中一些已经有了。精神工作不同于使用你的二头肌。 10. 不要一次写全部 - 使开发迭代 在编写代码分析和预测之前,您的客户/客户真正需要什么,然后选择您可以在短期内以高质量开发的MVF(最有价值的功能)。使用这样的迭代来部署质量更新,而不是腰部时间和资源对不合理的愿望和牺牲与质量。 11. 自动化VS手动 自动化是长期的100%成功。所以如果你有资源自动化的东西,现在应该做。你可能认为“只需要5分钟,为什么我应该自动化?但让我计算这个。例如,它是5个开发人员的日常任务。 5分钟* 5天* 21天* 12个月= 6 300分钟= 105小时= 13....

2018-02-07 14:03:12 · 1 min · Eddie Wang

JavaScript 高级技巧

0.1. 安全类型检测 javascript内置类型检测并不可靠 safari某些版本(<4)typeof正则表达式返回为function 建议使用Object.prototype.toString.call()方法检测数据类型 function isArray(value){ return Object.prototype.toString.call(value) === "[object Array]"; } function isFunction(value){ return Object.prototype.toString.call(value) === "[object Function]"; } function isRegExp(value){ return Object.prototype.toString.call(value) === "[object RegExp]"; } function isNativeJSON(){ return window.JSON && Object.prototype.toString.call(JSON) === "[object JSON]"; } 对于ie中一COM对象形式实现的任何函数,isFunction都返回false,因为他们并非原生的javascript函数。 在web开发中,能够区分原生与非原生的对象非常重要。只有这样才能确切知道某个对象是否有哪些功能 以上所有的正确性的前提是:Object.prototype.toString没有被修改过 0.2. 作用域安全的构造函数 function Person(name){ this.name = name; } //使用new来创建一个对象 var one = new Person('wdd'); //直接调用构造函数 Person(); 由于this是运行时分配的,如果你使用new来操作,this指向的就是one。如果直接调用构造函数,那么this会指向全局对象window,然后你的代码就会覆盖window的原生name。如果有其他地方使用过window.name, 那么你的函数将会埋下一个深藏的bug。 ==那么,如何才能创建一个作用域安全的构造函数?== 方法1 function Person(name){ if(this instanceof Person){ this.name = name; } else{ return new Person(name); } } 1....

2018-02-07 10:14:56 · 2 min · Eddie Wang

突然觉得自己好像没学过JS

0.1. 先看题:mean的值是什么? var scores = [10,11,12]; var total = 0; for(var score in scores){ total += score; } var mean = total/scores.length; console.log(mean); 0.2. 是11? 恭喜你:答错了! 0.3. 是1? 恭喜你:答错了! 0.4. 正确答案: 4 解释: for in 循环循环的值永远是key, key是一个字符串。所以total的值是:‘0012’。它是一个字符串,字符串'0012’/3,0012会被转换成12,然后除以3,结果是4。 0.5. 后记 这个示例是来自《编写高质量JavaScript的68个方法》的第49条:数组迭代要优先使用for循环而不是for in循环。 既然已经发布,就可能有好事者拿出去当面试题。这个题目很有可能坑一堆人。其中包括我。 这里涉及到许多js的基础知识. for in 循环是循环对象的索引属性,key是一个字符串。 数值类型和字符串相加,会自动转换为字符串 字符串除以数值类型,会先把字符串转为数值,最终结果为数值 正确方法 var scores = [10,11,12]; var total = 0; for(var i=0, n=scores.length; i < n; i++){ total += scores[i]; } var mean = total/scores....

2018-02-07 10:09:42 · 1 min · Eddie Wang