<script>
// 回调地狱
setTimeout(function(){
console.log("one");
setTimeout(function(){
console.log("two");
setTimeout(function(){
console.log("three");
},1000);
},1000);
},1000);
function one(cb){
console.log("one");
setTimeout(cb,1000);
}
function two(cb){
console.log("two");
setTimeout(cb,1000);
}
function three(cb){
console.log("three");
setTimeout(cb,1000);
}
//相对好一些了
one(function(){
two(three);
});
//类似ajax的用法
function trySomething(ok,err){
setTimeout(function(){
var num = Math.random();
if(num > 0.5)ok(num);
else err(num);
},1000);
}
trySomething(function(num){
console.log("Success"+num);
},function(num){
console.log("Sorry: "+num);
});
//类似coroutine的形式yield形式
function* foo(){
var index = 0;
while (index <= 2)
yield index++;
}
var iterator = foo();
console.log(iterator.next()); // { value: 0, done: false }
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
// jQuery的promise
var wait = function(ms) {
var dtd = $.Deferred();
setTimeout(dtd.resolve, ms);
// setTimeout(dtd.reject, ms);
// setTimeout(dtd.notify, ms);
return dtd.promise(); //此处也可以直接返回dtd
};
wait(2500).done(function() {
console.log('haha,师太,你可让老衲久等了');
}).fail(function() {
console.log('失败了');
}).progress(function(res) {
console.log('等待中...');
});
</script>
引言
为了深入的理解js的异步,我们先看这一段代码:
var start = new Date;
setTimeout(function(){
var end = new Date;
console.log("Time elasped:",end - start);
},500);
while(new Date - start < 1000){};
我们基本上会得到这样的结果:
Time elasped: 1013
发生了什么?为什么不是在500ms的时候执行setTimeout() ?
队列
调用setTimeout的时候,会有一个延迟事件排入队列,然后setTimeout调用之后的代码执行,接着是再下一行代码,直接再也没有任何代码,这时,js虚拟机才会问:队列里都有谁啊?我们平时还有另一种叫法:事件循环。js代码在运行期间只需要排队事件即可,而这事件在代码运行结束之前不会触发。
Ryan Dahl想要一个建立在某高级语言之上的事件驱动型服务器框架,js刚好就满足,为什么?因为js可以完美的实现非阻塞式IO。
console.log是异步的?
- webkit里的是异步的
- node里是严格同步的
Node中,process.nextTick允许事件调度成尽可能快的触发。触发频率可以超过10万次/称
高级浏览器中的requestAnimationFrame函数,有二个目标:一方面,允许以60帧每秒的速度运行JS动画,另一方面,避免了后台选项卡运行这些动画。从而节约CPU性能。
分布式事件
事件的蝴蝶偶然煽动了翅膀,整个应用到处都引发了反应。
- Node的EventEmitter
- Backbone的事件化模型
jQuery的自定义事件
只要对象带有PubSub接口,就可以称之为事件化对象。特殊情况出现在用于存储数据的对象因内容变化而发布事件时,这里用于存储数据的对象又称作模型。模型就是MVC中的M,MVC三层架构设计模式在最近几年里已经成为JS编程中最热点的主题之一,MVC的核心理念是应用程序应该以数据为中心,所以模型发和的事件会影响到DOM(MVC中的视图)和服务器(通过MVC中的控制器而产生影响)。
我们先来看看性感的backbone,ok,let's see the code:style = new Backbone.Model({font:"moyu-edu.com"});
model作为参数时只是代表了那个简单的可以传递的JSON对象。
style.toJSON();
但这个对象和普通的对象不同的是,这个model对象会在发生变化时发布通知:
style.on("change:font",function(model,font){
alert("Thank you guys for choosing"+font)
})
传统的jquery依赖于输入事件的处理器直接改变DOM,新式的js先改变模型,接着由模型触发事件而导致DOM的更新。在几乎所有的应用程序中,这种关注层面的分离都会带来更优雅、更直观的代码。
模型事件的传播
作为最简形式,MVC三层架构只包括相互联系的模型和视图:如果模型是这样变化的,那么DOM就要那样变化。不过MVC三层架构最大的利好出现在change事件冒泡上溯到数据树的时候。不用再去订阅数据树每片叶子上所发生的事件,而只需要订阅数据树根和枝处发生的事件就可以了。
为此,Backbone的Model对象常常组织成backbone集合的形式,其本质就是事件化数组,我们可以监听什么时候这些数组增减了model对象。