在 qooxdoo 应用程序中使用 Promises
Using Promises in a qooxdoo application
在一个qooxdoo class中,我有一组异步方法需要链接(序列化):
main: function() {
async1();
},
async1: function() {
var json = new qx.data.store.Json("http://...");
json.addListener("loaded", function(event) {
...
async2();
});
},
async2: function() {
// similar to async1
}
随着步骤数量的增加,链条变得难以追踪,代码变得不可读。我们可以做的是使用 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
}
这很好用,但只有在我们添加一些真正的逻辑之前。请记住,它是一个 qooxdoo class,其中包含很多内容 this
。但突然发现,在 then() 和 catch() 中使用的 async* 方法和匿名函数都将它们的 this
上下文绑定到 window
,一个全局对象。为了能够使用实际的 this
,我们可以执行重新绑定:
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.async1
实例方法时,为什么 this
没有隐式绑定?
如果在顶部添加 var self = this;
,在所有函数中,您可以通过调用 self:
来引用对象本身
main: function() {
var self = this;
new Promise(self.async1)
.then(function() {
return new Promise(self.async2);
}).then(function() {
return new Promise(self.async3);
}).catch(...);
},
勾选this answer out
基本上,从根本上看,你并没有做错什么。这就是上下文应该如何工作的。您真正需要的是针对您的特定用例的一些语法糖。您可以自己制作这些糖扩展或使用库来完成一些繁重的工作。
您还可以像 Danbopes 建议的那样重组您的代码并对其进行组织,这样您就可以减少内联绑定。这将使您更好地阅读流程。
在一个qooxdoo class中,我有一组异步方法需要链接(序列化):
main: function() {
async1();
},
async1: function() {
var json = new qx.data.store.Json("http://...");
json.addListener("loaded", function(event) {
...
async2();
});
},
async2: function() {
// similar to async1
}
随着步骤数量的增加,链条变得难以追踪,代码变得不可读。我们可以做的是使用 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
}
这很好用,但只有在我们添加一些真正的逻辑之前。请记住,它是一个 qooxdoo class,其中包含很多内容 this
。但突然发现,在 then() 和 catch() 中使用的 async* 方法和匿名函数都将它们的 this
上下文绑定到 window
,一个全局对象。为了能够使用实际的 this
,我们可以执行重新绑定:
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.async1
实例方法时,为什么 this
没有隐式绑定?
如果在顶部添加 var self = this;
,在所有函数中,您可以通过调用 self:
main: function() {
var self = this;
new Promise(self.async1)
.then(function() {
return new Promise(self.async2);
}).then(function() {
return new Promise(self.async3);
}).catch(...);
},
勾选this answer out
基本上,从根本上看,你并没有做错什么。这就是上下文应该如何工作的。您真正需要的是针对您的特定用例的一些语法糖。您可以自己制作这些糖扩展或使用库来完成一些繁重的工作。
您还可以像 Danbopes 建议的那样重组您的代码并对其进行组织,这样您就可以减少内联绑定。这将使您更好地阅读流程。