JavaScript 系列--JavaScript一些奇淫技巧的实现方法(一)简短的sleep函数,获取时间戳
一、前言
有些东西很好用,但是你未必知道;有些东西你可能用过,但是你未必知道原理。
实现一个目的有多种途径,俗话说,条条大路通罗马。发散一下大家的思维以及拓展一下知识面。
二、实现一个简短的sleep函数
sleep函数主要用来做延迟执行的,很多编程语言都有sleep函数,但是javascript没有这个函数,我们实现一下:
1、简单版本
function sleep(sleepTime){
for(var start = +new Date;+new Date - start<sleepTime;){}
}
var t1 = +new Date();
sleep(3000);
var t2 = +new Date();
console.log(t2-t1);
优点:简单粗暴,通俗易懂。
缺点:确实sleep了,但是卡死了,cpu会飙升,精确度不准
2、promise版本
// promise版本
function sleep(sleepTime){
return new Promise(resolve => setTimeout(resolve,sleepTime));
}
var t1 = +new Date();
sleep(3000).then(()=>{
var t2 = +new Date();
console.log(t2-t1);
})
优点:实际上用了setTimeout,没有形成进程阻塞,不会造成性能和负载问题。
缺点:虽然解决了回调函数的嵌套,但是还是不美观,而且异步不彻底,过程中停止执行。
3、generator版本
// generotor版本
function sleep(sleepTime){
return function(cb){
setTimeout(cb.bind(this), sleepTime);
}
}
function* genSleep(){
var t1 = +new Date();
yield sleep(3000);
var t2 = +new Date();
console.log(t2-t1);
}
async(genSleep);
function async(gen){
const iter = gen();
function nextStep(it){
if(it.done) return ;
if (typeof it.value === "function") {
it.value(function(ret) {
nextStep(iter.next(ret))
})
} else {
nextStep(iter.next(it.value));
}
}
nextStep(iter.next());
}
优点:跟promise一样优点,代码变得更简单干净。
缺点:就是每次都要执行 next() 显得很麻烦,虽然有 co(第三方包)可以解决,但就多包了一层,不好看,错误也必须按 co 的逻辑来处理,不爽。
co 之所以这么火并不是没有原因的,当然不是仅仅实现 sleep
这么无聊的事情,而是它活生生的借着generator/yield
实现了很类似 async/await
的效果!这一点真是让我三观尽毁刮目相看。
const co = require("co")
function sleep(sleepTime) {
return function(cb) {
setTimeout(cb.bind(this), sleepTime)
}
}
co(function*() {
const t1 = +new Date()
yield sleep(3000)
const t2 = +new Date()
console.log(t2 - t1)
})
4、async/await版本
function sleep(delay) {
return new Promise(reslove => {
setTimeout(reslove, delay)
})
}
!async function test() {
const t1 = +new Date()
await sleep(3000)
const t2 = +new Date()
console.log(t2 - t1)
}()
优点:同 Promise 和 Generator 优点。 Async/Await 可以看做是 Generator 的语法糖,Async 和 Await 相较于 * 和 yield 更加语义,另外各个函数都是扁平的,不会产生多余的嵌套,代码更加清爽易读。
缺点:ES7 语法存在兼容性问题,有 babel 一切兼容性都不是问题
5、开源的版本
在 javascript 优雅的写 sleep 等于如何优雅的不优雅,这里有 C++ 实现的模块:https://github.com/ErikDubbelboer/node-sleep
const sleep = require("sleep")
const t1 = +new Date()
sleep.msleep(3000)
const t2 = +new Date()
console.log(t2 - t1)
优点:能够实现更加精细的时间精确度,而且看起来就是真的 sleep 函数,清晰直白。
缺点:缺点需要安装这个模块node-sleep。
前端知识点:Async/Await是目前前端异步书写最优雅的一种方式
二、优雅获取时间戳
上面实现 sleep
函数,我们可以发现代码有 +new Date()
获取时间戳的用法,这只是其中的一种,下面就说一下其他两种以及 +new Date()
的原理。
1、普通版
var timestamp=new Date().getTime()
优点:具有普遍性,大家都用这个
缺点:应该没有吧
2、进阶版
var timestamp = (new Date()).valueOf()
valueOf 方法返回对象的原始值(Primitive,'Null','Undefined','String','Boolean','Number'五种基本数据类型之一),可能是字符串、数值或 bool 值等,看具体的对象。
优点:说明开发者原始值有一个具体的认知,让人眼前一亮。
缺点: 应该没有吧
3、Date.now()方法
Date.now()
Date.now()
方法返回自1970年1月1日 00:00:00 UTC到当前时间的毫秒数。类型为Number。因为 now() 是Date
的一个静态函数,所以必须以 Date.now() 的形式来使用。
优点:简单明了。
缺点:兼容性问题,ECMA-262 第五版中被标准化。
兼容性不支持时的兼容性代码:
if (!Date.now) {
Date.now = function now() {
return new Date().getTime();
};
}
4、终极版
var timestamp = +new Date()
优点:对 JavaScript 隐式转换掌握的比较牢固的一个表现
缺点:应该没有吧
我们来分析一下,为什么+new Date()拿到的时间戳?
那就是隐式转换,实质上还是调用了valueOf()的方法。
注意:
(1)一元+ 运算符
一元 +
运算符将其操作数转换为 Number
类型并反转其正负。注意负的 +0
产生 -0
,负的 -0
产生 +0
。
+new Date() 相当于 ToNumber(new Date())
(2)toString
用来返回对象的字符串表示。
var obj = {};
console.log(obj.toString());//[object Object]
var arr = [];
console.log(arr.toString());//""空字符串
var date = new Date(); // Tue May 28 2019 22:05:58 GMT+0800 (中国标准时间)
console.log(date.toString());//"Tue May 28 2019 22:05:58 GMT+0800 (中国标准时间)"
(3)valueOf()方法返回对象的原始值
valueOf()方法返回对象的原始值,可能是字符串,述职或boolean值,看具体的对象。
var obj = {
name: "saucxs"
}
console.log(obj.valueOf()) //Object {name: "saucxs"}
var arr1 = [1,3]
console.log(arr1.valueOf()) //[1,3]
var date = new Date()
console.log(date.valueOf())//1456638436303
// 如代码所示,三个不同的对象实例调用valueOf返回不同的数据
原始值指的是 'Null','Undefined','String','Boolean','Number','Symbol'
6种基本数据类型之一,上面已经提到过这个概念,这里再次申明一下。
最后分解一下其中的过程:+new Date():
(1)运算符 new 的优先级高于一元运算符 +,所以过程可以分解为:var time=new Date();+time
(2)根据上面提到的规则相当于:ToNumber(time)
(3)time 是个日期对象,根据 ToNumber 的转换规则,所以相当于:ToNumber(ToPrimitive(time))
(4)根据 ToPrimitive 的转换规则:ToNumber(time.valueOf()),time.valueOf() 就是 原始值 得到的是个时间戳,假设 time.valueOf()=1503479124652
(5)所以 ToNumber(1503479124652) 返回值是 1503479124652 这个数字。
前端知识点:隐式转换的妙用
JavaScript 系列--JavaScript一些奇淫技巧的实现方法(一)简短的sleep函数,获取时间戳的更多相关文章
- JavaScript 系列--JavaScript一些奇淫技巧的实现方法(二)数字格式化 1234567890转1,234,567,890;argruments 对象(类数组)转换成数组
一.前言 之前写了一篇文章:JavaScript 系列--JavaScript一些奇淫技巧的实现方法(一)简短的sleep函数,获取时间戳 https://www.mwcxs.top/page/746 ...
- JavaScript 系列--JavaScript一些奇淫技巧的实现方法(三)数字取整,数组求和
一.前言 简短的sleep函数,获取时间戳:https://www.mwcxs.top/page/746.html 数字格式化 1234567890 --> 1,234,567,890:argr ...
- 12个实用的 Javascript 奇淫技巧
这里分享12个实用的 Javascript 奇淫技巧.JavaScript自1995年诞生以来已过去了16个年头,如今全世界无数的网页在依靠她完成各种关键任务,JavaScript曾在Tiobe发布的 ...
- javascript之奇淫技巧
最近准备面试,复习一下javascript,整理了一些javascript的奇淫技巧~ //为兼容ie的模拟Object.keys() Object.showkeys = function(obj) ...
- 优化DP的奇淫技巧
DP是搞OI不可不学的算法.一些丧心病狂的出题人不满足于裸的DP,一定要加上优化才能A掉. 故下面记录一些优化DP的奇淫技巧. OJ 1326 裸的状态方程很好推. f[i]=max(f[j]+sum ...
- NGINX的奇淫技巧 —— 5. NGINX实现金盾防火墙的功能(防CC)
NGINX的奇淫技巧 —— 5. NGINX实现金盾防火墙的功能(防CC) ARGUS 1月13日 发布 推荐 0 推荐 收藏 2 收藏,1.1k 浏览 文章整理中...... 实现思路 当服务器接收 ...
- NGINX的奇淫技巧 —— 3. 不同域名输出不同伺服器标识
NGINX的奇淫技巧 —— 3. 不同域名输出不同伺服器标识 ARGUS 1月13日 发布 推荐 0 推荐 收藏 6 收藏,707 浏览 大家或许会有这种奇葩的需求...要是同一台主机上, 需要针对不 ...
- NGINX的奇淫技巧 —— 6. IF实现数学比较功能 (1)
NGINX的奇淫技巧 —— 6. IF实现数学比较功能 (1) ARGUS 1月13日 发布 推荐 0 推荐 收藏 3 收藏,839 浏览 nginx的if支持=.!= 逻辑比较, 但不支持if中 & ...
- Zepto源码分析(二)奇淫技巧总结
Zepto源码分析(一)核心代码分析 Zepto源码分析(二)奇淫技巧总结 目录 * 前言 * 短路操作符 * 参数重载(参数个数重载) * 参数重载(参数类型重载) * CSS操作 * 获取属性值的 ...
随机推荐
- HDOJ1059(多重部分和问题)
#include<cstdio> #include<cstring> using namespace std; +; ]; int dp[SIZE]; bool check() ...
- java继承示例
package day07; class Fu { int num = 5; } class Zi extends Fu { int num =7; void show() { int num =9; ...
- nmap 快速扫描所有端口
nmap -sT -sV -Pn -v xxx.xxx.xxx.xxx nmap -sS -p 1-65535 -v 192.168.1.254参数:-sS TCP SYN扫描 nmap ...
- CentOS7下yum方式安装mysql5.6
在Centos7中用MariaDB代替了mysql数据库.所以在新安装MySQL前必须做好对系统的清理工作. 一.清理CentOS7下的MariaDB. [root@localhost ~]#rpm ...
- [xdoj1158]阶乘求逆元(常用于求组合数)
http://acm.xidian.edu.cn/problem.php?id=1158 解题关键:此题注意将$\sum\limits_{i = 0}^x {C_x^iC_y^{i + k}}$转化为 ...
- Flask05 cookie、类视图、方法视图、自己的404页面
1 什么是cookie 就是网站存放到你浏览器中的一部分固定内容:当你下次访问我这个网站的时候,你会把之前我存放到你浏览器中的数据带回来给我 你要先登录(用户名.密码) -> ...
- C++哪些函数不能是虚函数
1. inline是编译时展开,必须有实体:(不考虑不展开的假inline) 2. static属于class自己的,也必须有实体: 3. 构造函数.复制构造函数.virtual函数基于vta ...
- MAC电脑下Pycharm新建模板默认添加作者时间等信息
在pycharm使用过程中,对于每次新建文件的shebang行和关于代码编写者的一些个人信息快捷填写,使用模板的方式比较方便. 方法如下: 1.打开pycharm,选择Pycharm-preferen ...
- AOP常用注解
1.@Aspect 配置切面Bean,和<bean.../>元素进行配置无区别,一样支持依赖注入来配置属性值: 如果启动了Spring的"零配置"特性,一样可以让Spr ...
- DataGridView控件对Column的设置
http://stackoverflow.com/questions/18666582/datagridview-autofit-and-fill 1.Column覆盖所有width: dgv.Aut ...