Hi to all,switching back and forth between javascript and flex (actually AS), I found that the most useful and fantastic pattern that is raising in the JS world are Promises.Promises are a programming construct that have been around since 1976, and even Dojo have a promise package: http://dojotoolkit.org/reference-guide/1.9/dojo/promise.htmlIn short, a promise represents a value that is not yet known and a deferred represents work that is not yet finished.The beauty is that you can concatenate your functions like this:
queryForGeometry()
.then(fillGeometry)
.then(queryForKeygis)
.then(fillKeygis)
.then(completeUpdate)
.done();
After some research I've found this library: https://github.com/CodeCatalyst/promise-as3And finally I can say goodbye to nested callbacks! And with only one line of code you can adapt your query and identify to use promise!
// Somewhere in your code, at the load of the Application
Promise.registerAdapter( AsyncTokenAdapter.adapt );
var task:QueryTask = new QueryTask(Endpoint.QUERY_LAYER_FOR_BUILDING);
var query:Query = new Query();
query.where = "1=1";
query.outFields = ["*"];
// query initialisation ...
Promise.when(task.execute(query)).then(doSomethingWithQueryResult);
function doSomethingWithQueryResult(featureSet:FeatureSet):void {
...
}
With only one query is really simple and maybe not so revolutionary, but when you have more query that depends on other query this pattern simplify a lot my code and it's much simple to read.The functions are all on the same level, executed in sequence and no more nested!
function queryForGeometry():Promise {
...
}
function fillGeometry(featureSet:FeatureSet, token:Object = null):Graphic {
...
}
function queryForKeygis(feature:Graphic):Promise {
...
}
function fillKeygis(featureSet:FeatureSet, token:Object = null):Object {
...
}
You can even do some thing like this, call a webservice, receive the result, the execute a query with some data...easy!
public class Http {
public static function get(uri:String):Promise {
var service:HTTPService = new HTTPService();
service.url = encodeURI(uri);
var header:Object = new Object();
header["Accept"] = "application/json; charset=utf-8";
service.headers = header;
return Promise.when(service.send());
}
}
// In another class, some function to query
Http.get("http://.../streets/1").then(parseJson).then(queryGISLayerWithId).done();
Happy Coding!