移动web app开发必备 - Deferred 源码分析
2013-07-04 09:32
169 查看
姊妹篇 移动web app开发必备 - 异步队列 Deferred
在分析Deferred之前我觉得还是有必要把老套的设计模式给搬出来,便于理解源码!
它定义了一种一对多的关系让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。
使用观察者模式的好处:
支持简单的广播通信,自动通知所有已经订阅过的对象。
页面载入后目标对象很容易与观察者存在一种动态关联,增加了灵活性。
目标对象与观察者之间的抽象耦合关系能够单独扩展以及重用。
在这种模式中,有两类对象,分别是“观察者-Observer”和“目标对象-Subject”。
目标对象中保存着一份观察者的列表,当目标对象的状态发生改变的时候就主动向观察者发出通知(调用观察者提供的方法),从而建立一种发布/订阅的关系。
这一种发布/订阅的关系常用于实现事件、消息的处理系统。
View Code
d.callbacks就是订阅收集的具体观察者感兴趣的内容,也就是callback or errback
匹配出正确的回调方法,执行
d.result = fn(d.result) 传入回调函数需要的参数
单一的流程就执行完毕了
我们看看复杂点的构造
执行流程:
等待在一个列表的所有值的递延的对象,或者开始一群延迟操作和运行回调链当第一个成功还是失败了
等待d1, d2都加载完毕后接受到所有的values后,deferred.all运行作用域链,当然也一样可以提供成功或者失败
返回的result将会是数组格式的
或者传入配置参数:
fireOnFirstResult: true 只要返回第一个d1处理
fireOnFirstError: true 只返回第一个错误的处理
最后看2个API没有给出的接口
执行流程:
一个回调函数的返回值被传递到下一个回调。
当一个回调返回一个延迟对象,原来的延迟将透明地等待其他接收它的值,然后运行它自己的回调链使用该值。我们把这种叫做嵌套。
总结:
现在我们可以用deferred对象做很多事了,返回它,将它传递给另一个函数,等。
随后的回调注册在deferred将收到返回的值从最内层的回调:result1+ result2。
用起来是不是很爽!
考虑这章拉的太长了,大家看的会有点小闷,所以下一节就开始队列的源码分析了
在分析Deferred之前我觉得还是有必要把老套的设计模式给搬出来,便于理解源码!
观察者模式
观察者模式( 又叫发布者-订阅者模式 )应该是最常用的模式之一.它定义了一种一对多的关系让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。
使用观察者模式的好处:
支持简单的广播通信,自动通知所有已经订阅过的对象。
页面载入后目标对象很容易与观察者存在一种动态关联,增加了灵活性。
目标对象与观察者之间的抽象耦合关系能够单独扩展以及重用。
在这种模式中,有两类对象,分别是“观察者-Observer”和“目标对象-Subject”。
目标对象中保存着一份观察者的列表,当目标对象的状态发生改变的时候就主动向观察者发出通知(调用观察者提供的方法),从而建立一种发布/订阅的关系。
这一种发布/订阅的关系常用于实现事件、消息的处理系统。
观察者模式类图
function _run(d) { if (d.running) return var link, status, fn if (d.pauseCount > 0) return while (d.callbacks.length > 0) { link = d.callbacks.shift() status = (d.result instanceof Failure) ? 'errback' : 'callback' fn = link[status] if (typeof fn !== 'function') continue try { d.running = true d.result = fn(d.result) d.running = false if (d.result instanceof Deferred) { d.pause() _nest(d) return } } catch (e) { if (Deferred.consumeThrownExceptions) { d.running = false var f = new Failure(e) f.source = f.source || status d.result = f if (d.verbose) { console.warn('uncaught error in deferred ' + status + ': ' + e.message) console.warn('Stack: ' + e.stack) } } else { throw e } } } }
View Code
运行流程
其中d就是传入的异步对象了d.callbacks就是订阅收集的具体观察者感兴趣的内容,也就是callback or errback
匹配出正确的回调方法,执行
d.result = fn(d.result) 传入回调函数需要的参数
单一的流程就执行完毕了
我们看看复杂点的构造
案例分析二
等待许多异步数据源function asynchronous(delay,name) { var d = new deferred.Deferred() setTimeout(function() { d.resolve('执行'+name) }, delay || 1000); return d }; var d1 = new asynchronous(2000, 'd1'); var d2 = new asynchronous(3000, 'd2'); deferred.all([d1, d2]).then(function(result){ console.log(result) //["执行d1", "执行d2"] }).thenCall(console.log(11111));
执行流程:
等待在一个列表的所有值的递延的对象,或者开始一群延迟操作和运行回调链当第一个成功还是失败了
等待d1, d2都加载完毕后接受到所有的values后,deferred.all运行作用域链,当然也一样可以提供成功或者失败
返回的result将会是数组格式的
convert ['a', 'b', 'c'] to 'abc'
或者传入配置参数:
fireOnFirstResult: true 只要返回第一个d1处理
fireOnFirstError: true 只返回第一个错误的处理
deferred.all([d1, d2],{fireOnFirstResult: true}).then(function(result){ console.log(result) //["执行d1"] }).thenCall(console.log(11111));
最后看2个API没有给出的接口
dAll.failCall(console.error) dAll.then(join).thenCall(console.log)
案例分析三
任意组合模式function asynchronous(delay,name) { var d = new deferred.Deferred() setTimeout(function() { d.resolve('执行'+name) }, delay || 1000); return d }; var d1 = new asynchronous(2000, 'd1'); var d = d1.then(function(result1) { var d2 = new asynchronous(200, 'd2'); return d2.then(function(result2) { return result }) }).then(function(data) { console.log(data) return data })
执行流程:
一个回调函数的返回值被传递到下一个回调。
当一个回调返回一个延迟对象,原来的延迟将透明地等待其他接收它的值,然后运行它自己的回调链使用该值。我们把这种叫做嵌套。
总结:
现在我们可以用deferred对象做很多事了,返回它,将它传递给另一个函数,等。
随后的回调注册在deferred将收到返回的值从最内层的回调:result1+ result2。
用起来是不是很爽!
考虑这章拉的太长了,大家看的会有点小闷,所以下一节就开始队列的源码分析了
相关文章推荐
- 移动web app开发必备 - Deferred 源码分析
- 移动web app开发必备 - 异步队列 Deferred
- 移动web app开发必备 - 异步队列 Deferred
- 移动web app开发必备 - zepto事件问题
- 对移动开发中蓝牙温湿度源码的部分分析
- 全栈工程师必备技能--前端开发、后台开发、移动开发以及第三方开发微信公众号...界面设计、产品设计、数据库
- TreeFrog (C++ Web Framework)开发之源码分析
- golang 移动应用例子 example/basic 源码框架分析
- 移动应用开发必备工具盘点
- netty源码分析之-开发过程中重要事项分析(7)
- C#使用Xamarin开发可移植移动应用进阶篇(6.使用渲染器针对单个平台自定义控件..很很很很重要..),附源码
- 霸王链小程序开发源码分析
- 使用 jQuery Mobile 与 HTML5 开发 Web App —— 12 jQuery Mobile 页面事件与 deferred
- C#使用Xamarin开发可移植移动应用进阶篇(6.使用渲染器针对单个平台自定义控件..很很很很重要..),附源码
- android源码大放送(实战开发必备)
- Struts源码粗略分析一:准备开发环境
- 8款流行的移动应用程序开发必备工具
- 移动终端web开发必备知识
- 网站开发中必备的8个 jQuery 效果【附源码】
- C#开发的人脸左右相似度计算软件源码分析