In a qooxdoo class, I have a set of asynchronous methods that need to be chained (serialized):
main: function() {
async1();
},
async1: function() {
var json = new qx.data.store.Json("http://...");
json.addListener("loaded", function(event) {
...
async2();
});
},
async2: function() {
// similar to async1
}
As the number of the steps grows, the chain becomes hard to trace, and the code gets unreadable. What we can do is rewrite our code using Promises:
main: function() {
new Promise(this.async1)
.then(function() {
return new Promise(this.async2);
}).then(function() {
return new Promise(this.async3);
}).catch(...);
},
async1: function(resolve, reject) {
var json = new qx.data.store.Json("http://...");
json.addListener("loaded", function(event) {
...
resolve();
});
},
async2: function(resolve, reject) {
// similar to async1
}
This works great but only until we add some real logic. Remember it's a qooxdoo class with a lot of stuff encapsulated into this. But suddenly it turns out that both async* methods and anonymous functions used in then() and catch() have their this context bound to window, a global object. To be able to use actual this, we can perform rebind:
main: function() {
new Promise(this.async1.bind(this))
.then(function() {
this.doSomeStuff();
return new Promise(this.async2.bind(this));
}.bind(this)).then(function() {
return new Promise(this.async3.bind(this));
}.bind(this)).then(function() {
this.doSomeFinalStuff();
}.bind(this)).catch(function() {
this.doStuffOnError();
}.bind(this));
},
async1: function(resolve, reject) {
this.doOtherStuff();
var json = new qx.data.store.Json("http://...");
json.addListener("loaded", function(event) {
...
resolve();
});
}
This finally works, but doh, ugly is the code! Are there any ways to get rid of those manual binds? Why isn't this implicitly bound when we reference this.async1, an instance method?