列表
- JavaScript事件循环
- 测试金字塔
- stub
JavaScript事件循环理解
javaScript语言的核心就是单线程事件循环,早期在浏览器中因为很难去处理用户多个行为对应多线程的操作设置。Nodejs也继承了这一友好特性。
按照阮一峰老师所说,JavaScript有一个执行栈和任务队列,我的理解是执行栈按照同步方式执行代码,存放同步代码和异步代码标记,任务队列存放异步回调。这和堆栈的处理有异曲同工之妙。
事件循环步骤
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
为了理解事件循环,我写了如下的程序测试:
console.log("start");
setTimeout(function(){
console.log("setTimeout");
},10);
for(var i = 0;i < 100;i++){
console.log("Loop",i);
}
console.log("end");
结果果然是先输出end之后才会有setTimeout。也就是说在任务栈执行完毕后才会去读取任务队列。
以下是setTimeout需要注意的地方,验证了我的猜想:
HTML5标准规定了setTimeout()的第二个参数的最小值(最短间隔),不得低于4毫秒,如果低于这个值,就会自动增加。在此之前,老版本的浏览器都将最短间隔设为10毫秒。另外,对于那些DOM的变动(尤其是涉及页面重新渲染的部分),通常不会立即执行,而是每16毫秒执行一次。这时使用requestAnimationFrame()的效果要好于setTimeout()。
需要注意的是,setTimeout()只是将事件插入了"任务队列",必须等到当前代码(执行栈)执行完,主线程才会去执行它指定的回调函数。要是当前代码耗时很长,有可能要等很久,所以并没有办法保证,回调函数一定会在setTimeout()指定的时间执行。
关于nodejs事件循环函数的理解
process.nextTick
process.nextTick方法可以在当前"执行栈"的尾部----下一次Event Loop(主线程读取"任务队列")之前----触发回调函数。也就是说,它指定的任务总是发生在所有异步任务之前。
setImmediate
多个process.nextTick语句总是在当前"执行栈"一次执行完,多个setImmediate可能则需要多次loop才能执行完。
测试代码
console.log("start");
process.nextTick(function(){
console.log("nextTick");
});
setTimeout(function(){
console.log("setTimeout1");
},10);
setImmediate(function(){
console.log("setImmediate1");
setImmediate(function(){
console.log("setImmediate2");
});
});
setTimeout(function(){
console.log("setTimeout2");
},200);
for(var i = 0;i < 10000;i++){
console.log("Loop",i);
}
console.log("end");
传送门
JavaScript 运行机制详解:再谈Event Loop
44.理解事件循环一(浅析)
测试金字塔
金字塔分为5层,最一层的是单元测试,是针对类库和程序集来进行测试;第二层为组件级的测试,我的理解是dll和接口级的测试;第三层为服务级的测试,像我们做GIS的,可以理解为地图服务,定位服务等;第四层为界面级的测试(如自动化UI测试);最上面一层为手动测试,运行已经集成的系统,手工对系统的运行结果和预期结果比较。
传送门
10个常见的Node.js面试题
nodejs框架
单元测试
关于对测试金字塔的理解收获共享
stub
用于替代模拟你用到的方法,返回指定的结果。
看到的资料中有提到sinon的依赖库,用于测试模拟。
传送门
对 stub 和 mock 的理解
sinon
带你入门带你飞Ⅰ 使用Mocha + Chai + Sinon单元测试Node.js