微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

dojo异步编程 dojo/Deferred

Email:longsu2010 at yeah dot net

JavaScript的事件回调真的很棒,比如AJAX获取数据在数据返回时执行某函数,比如websocket获取数据后执行函数,比如JSONP……

dojo的dojo/Deferred用于开启一个异步程序,对于封装通用组件特别有用。

下面介绍dojo/Deferred的用法, 从一个小例子开始。(本例使用chrome)

require(["dojox/store/proxyStore","dojo/Deferred"],function( ProxyStore,Deferred){
	var deferred = new Deferred();
	// 设置回调函数
	deferred.then(function(args){
		console.log(args);
	},function(args){
		console.log(args);
	},function(args){
		console.log(args);
	});
	// 更新状态
	deferred.progress("progress");
	// 正常完成
	deferred.resolve("resolve");
	// 有错误发生
	// deferred.reject();
	// 取消异步程序
	// deferred.cancel();
});	
可以看出使用Deferred需要先创建一个Deferred对象,之后用then方法设置该对象的回调函数,之后可以用例子中的其他几个函数来更新Deferred对象的状态。Deferred对象会根据不同的状态来调用不同的回调函数
Deferred对象除了提供例子中改变状态的函数外还提供了判断状态的函数,各函数含义:
0、then:设置回调函数,一共可设置三个回调函数,第一参数在调用resolve后回调,第二参数在调用reject和cancel后回调,第三参数在调用progress后回调。
1、resolve:该deferred完成。
2、reject:该deferred发生错误
3、cancel:取消所有回调,即不再关心该deferred对象。
4、progress:更新deferred对象状态。
5、isResolved:若调用过resolve函数返回true
6、isRejected:若调用过reject函数返回true
7、isFulfilled:若调用过resolve、reject或cancel三者之一返回true
8、isCanceled:若调用过cancel函数返回true

仅从上面的例子还真看不出这东西有什么实际用处。那如果让你封装一个websocket请求的公共模块呢?要求该模块提供一个query方法,通过query方法获取websocket服务端的数据。由于websocket是异步的,query的返回值不可能是获取的数据,这时候返回一个Deferred对象就比较合适了。如下为该模块的伪代码(仅示例性的写写)。

define(["dojo/Deferred"],function(Deferred){
	var deferreds = [];
	var websocket = new WebSocket("ws://127.0.0.1:12580");
	websocket.onmessage = function(evt){
		var data = JSON.parse(evt.data);
		if(data.success){
			deferreds.shift().resolve(data);
		}else{
			deferreds.shift().reject(data);
		}
	};
	
	return {
		query : function(url){
			var deferred = new Deferred();
			deferreds.push(deferred);
			websocket.send(url);
			return deferred;
		}
	}; 	
});
该模块的使用方法为:

// 省略模块导入代码, 假设导入名字为dataProxy。

var rs = dataProxy.query("name=ddd");
rs.then(function(args){
	console.log("获取数据成功, 数据为:",args);
},function(args){
	console.log("获取数据失败,错误信息为:",args);
});
可以看出,Deferred对象很多时候是作为函数返回值使用的,之后在该返回值上用then注册回调函数,当Deferred对象状态改变时回调函数被执行。

值得说明的一点是then的返回值仍然是一个异步对象,所以可以这样写

rs.then(function(){
	return 1;
}).then(function(){
	return 2;
}).then(function(){
	return 3;
})

执行顺序为从前到后。

有时间建议读一读dojo/Deferred.js源码,代码写的很不错。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我有一个网格,可以根据更大的树结构编辑小块数据.为了更容易知道用户保存了什么,我希望当用户第一次看到网格时,网格处于不可编辑状态.当用户准备好后,他们可以单击编辑按钮,这将使网格的某些部分可编辑.然后,有一个保存或取消按钮可以保存更改或还原.在大多数情况下它是有效的.但
我即将开始开发一款教育性的视频游戏.我已经决定以一种我可以轻松打包为Web,Mobiles和可能的Standalone版本的方式来实现这一目标.我不想使用Flash.因此,我确信(无论如何我会听取建议)使用JavaScript和SVG.我正在对这个问题进行大量研究,但我很难把各个部分放在一起.我知道Raphae
我正在使用带有Grails2.3.9的Dojo1.9.DojoNumberTextBox小部件–我在表单中使用–将固定格式(JavaScript基本格式)的实数值(例如:12.56)设置为HTML表单输入字段(但根据浏览器区域设置显示/编辑它们,所以用户总是看到格式正确的数字).另一方面,Grails期望输入字段根据浏览器
1.引言鉴于个人需求的转变,本系列将记录自学arcgisapiforjavaScript的学习历程,本篇将从最开始的arcgisapiforjavaScript部署开始,个人声明:博文不在传道受业解惑,旨在方便日后复习查阅。由于是自学,文章中可能会出现一些纰漏,请留言指出,不必留有情面哦!2.下载ArcGISforDe
我正在阅读使用dojo’sdeclare进行类创建的语法.描述令人困惑:Thedeclarefunctionisdefinedinthedojo/_base/declaremodule.declareacceptsthreearguments:className,superClass,andproperties.ClassNameTheclassNameargumentrepresentsthenameofthec
我的团队由更多的java人员和JavaScript经验丰富组成.我知道这个问题曾多次被问到,但为了弄清楚我的事实,我需要澄清一些事情,因为我在客户端技术方面的经验非常有限.我们决定使用GWT而不是纯JavaScript框架构建我们的解决方案(假设有更多的Java经验).这些是支持我的决定的事实.>
路由dojo/framework/srcouting/README.mdcommitb682b06ace25eea86d190e56dd81042565b35ed1Dojo应用程序的路由路由FeaturesRoute配置路径参数RouterHistoryManagersHashHistoryStateHistoryMemoryHistoryOutletEventRouterContextInjectionOutl
请原谅我的无知,因为我对jquery并不熟悉.是否有dojo.connect()的等价物?我找到了这个解决方案:http:/hink-robot.com/2009/06/hitch-object-oriented-event-handlers-with-jquery/但是没有断开功能!你知道jquery的其他解决方案吗?有jquery.connect但这个插件在我的测试中不起作用.
与java类一样,在dojo里也可以定义constructor 构造函数,在创建一个实例时可以对需要的属性进行初始化。//定义一个类mqsy_yjvar mqsy_yj=declare(null,{     //thedefaultusername    username: "yanjun",          //theconstructor   
我一直在寻找一些最佳实践,并想知道Dojo是否具有框架特定的最佳实践,还是最好只使用通用的Javascript标准?特别是我主要是寻找一些功能和类评论的指导方针?解决方法:对于初学者来说,这是项目的风格指南:DojoStyleGuide