JavaScript异步编程
来源:互联网 发布:手机屏幕画笔软件 编辑:程序博客网 时间:2024/06/16 04:18
Javascript语言的执行环境是”单线程”(single thread)。所谓”单线程”,就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。
Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。
“异步模式”非常重要。在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,”异步模式”甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降,很快就会失去响应。
然而,异步执行最大的问题就是执行顺序。
假定有两个函数f1和f2,后者等待前者的执行结果。
function f2() { console.log("f2");}
一、回调函数
function f1(callback) { console.log("f1"); setTimeout(function(){ callback(); }, 1000);}// 执行f1(f2);
优点是简单、容易理解和部署;
缺点是不利于代码的阅读和维护,各个部分之间高度耦合(Coupling),流程会很混乱,而且每个任务只能指定一个回调函数。
二、事件监听
这里采用的jQuery的写法
var eventable = { on: function(event, cb) { $(this).on(event, cb); }, trigger: function (event, args) { $(this).trigger(event, args); }}var f1 = { run: function() { setTimeout(function(){ // f1执行逻辑 console.log("f1"); f1.trigger("done"); }, 1000); }};$.extend(f1, eventable);f1.on("done", f2);f1.run();
优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以”去耦合”(Decoupling),有利于实现模块化;
缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。
补充:<注意上述f1的写法>
当使用eval()函数或者是Function构造函数以及使用setTimeout()传一个字符串参数时都会发生“双重解释”。
eval("console.log('Hello Eval!')");var sayHello = new Function("console.log('Hello Function!')");setTimeout("console.log('Hello setTimeout!')", 1000);
这些操作不能在初始化的解析过程中完成的,也就是说在JavaScript代码运行的同时必须新启动一个解析器来解析新的代码。性能消耗较大。
console.log('Hello Eval!')var sayHello = function() { console.log('Hello Function!')};setTimeout(function(){ console.log('Hello Function!')}, 1000)
三、发布/订阅
使用jQuery插件https://github.com/cowboy/jquery-tiny-pubsub
jQuery.subscribe("done", f2);function f1(){ // f1执行逻辑 console.log("f1"); setTimeout(function(){ jQuery.publish("done"); }, 1000);}f1();jQuery.unsubscribe("done", f2); // 取消订阅
这种方法的性质与”事件监听”类似,但是明显优于后者。因为我们可以通过查看”消息中心”,了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。
四、Promises对象
function f1(){ var dfd = $.Deferred(); setTimeout(function () { // f1的任务代码 console.log("f1"); dfd.resolve(); }, 500); // 在原来的deferred对象上返回另一个deferred对象,后者只开放与改变执行状态无关的方法(比如done()方法和fail()方法),屏蔽与改变执行状态有关的方法(比如resolve()方法和reject()方法),从而使得执行状态不能被改变。 return dfd.promise();}f1().then(f2);
好处:如果一个任务已经完成,再添加回调函数,该回调函数会立即执行。所以,你不用担心是否错过了某个事件或信号。这种方法的缺点就是编写和理解,都相对比较难。
参考地址:http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html
- javascript 异步编程javascript
- javascript 异步编程
- javascript 异步编程2
- JavaScript异步编程
- JavaScript异步编程
- JavaScript异步编程
- javascript异步编程延伸
- javascript 异步编程
- Javascript异步编程
- JavaScript异步编程原理
- javascript 异步编程2
- JavaScript异步编程
- javascript 异步编程
- JavaScript 异步编程
- Javascript异步编程
- 探索Javascript异步编程
- javascript异步编程
- javascript异步编程实例
- iOS中旋转加载动画的实现
- Struts1.1应用初步
- Fedora23 安装 BCM43142 无线网卡驱动
- 实现炫酷的卡片式动画!
- BIRT4.4导出xlsx文件单sheet
- JavaScript异步编程
- nyoj-35 表达式求值
- 做android爽到爆的东西,一般人我不告诉他
- 使用CALayer的Mask实现注水动画效果
- 安卓开发之动态注册网络监听广播
- 栈+递归+htmlunit分层访问动态页面
- Linux上vi(vim)编辑器使用教程
- 编译OpenCV2.4.x + CUDA7.0 + vs2013
- 程序员不可不知的英文词汇(5)