dojo非同期プログラミングdojo/deferred

4427 ワード

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:コールバック関数を設定し、3つのコールバック関数を設定できます.第1のパラメータはresolveを呼び出した後にコールバックし、第2のパラメータはrejectとcancelを呼び出した後にコールバックし、第3のパラメータは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メソッドによりwebsocketサービス側のデータを取得するqueryメソッドが要求される.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ソース、コードはよく書けています.