我在JavaScript中编写一个具有以下属性的构造函数:
function WhizBang() {
var promise;
this.publicMethod_One = function publicMethod_One() { ... };
this.publicMethod_Two = function publicMethod_Two() { ... };
promise = asyncInit();
}
因此,调用new WhizBang()
将启动asyncInit()
进程。从上面的代码中可以明显看出,在调用asyncInit()
之前,接口中的所有公共方法都不会运行。
因此,publicMethod_One()
的定义可能如下所示:
function publicMethod_One() {
promise
.then( doStuff )
.catch( reportInitFailure )
;
function doStuff() { ... }
function reportInitFailure() { ... }
}
doStuff()
中发生的一些事情是异步的;其中一些人不是。
所以,如果我班级的最终用户做了这样的事情:
function main() {
var whizBang = new WhizBang();
whizBang
.publicMethod_One()
.publicMethod_Two()
;
}
在publicMethod_One()
关闭之前,我们会致电asyncInit()
。在publicMethod_Two()
和asyncInit()
关闭之前,才会调用publicMethod_One()
。
如何定义我的类方法以使它们可链接?
我认为我需要做的是定义一个类,其公共方法等同于在promise上调用then()
,然后是类特定的实现内容。
互联网,停了!
(在答案中使用Bluebird Promise Library的加分点。)
答案 0 :(得分:4)
你现在拥有的实际上非常好。由于您在承诺中缓存asyncInit
的结果并且每个人都等待相同的承诺 - 这些函数中的任何代码都无法在承诺完成之前运行。
function publicMethod_One() {
promise // the fact you're starting with `promise.` means it'll wait
.then( doStuff )
.catch( reportInitFailure );
}
因此,不是强迫人们等待使用publicMethod_One
他们已经可以立即调用它,而doStuff
之类的方法只会执行已经解决的承诺。
好吧,就像你注意到你的代码有一个重大问题一样,给定的方法无法知道何时运行或者对方法进行排序 - 你可以通过两种方式解决这个问题:
this
并对承诺进行排队。让我们看看这两种方法:
这意味着您的所有方法都会返回实例,它们也必须排队,以便不会立即发生事情。#39;我们可以通过在每次调用时修改promise
来实现此目的:
function publicMethod_One() {
promise = promise // note we're changing it
.then( doStuff )
.catch( reportInitFailure );
return this; // and returning `this`
}
您可能还希望公开一个返回当前promise的.ready
方法,以便可以从外部等待操作序列:
function ready(){
return this.promise;
}
这可以启用以下内容:
var ready = new WhizBang().publicMethod_One().publicMethod_One().ready();
ready.then(function(){
// whizbang finished all operations
}); // can also add error handler
在我看来,这是一种更简单的方法,所有方法都会返回他们创建的承诺,以便他们可以单独等待:
function publicMethod_One() {
return promise // note we're returning and not changing it
.then( doStuff )
.catch( reportInitFailure );
}
这很好,因为异步操作暴露在外面。
链接是可行的,因为您将{blue}与.bind
一起使用:
var whiz = new WhizBang();
var res = Promise.bind(whiz).then(whiz.publicMethod_one)
.then(whiz.publicMethod_one);
res.then(function(){
// all actions completed, can also use return values easier.
});
但优点是从外部更容易推理 - 因此我更喜欢这种方法。就个人而言,我总是喜欢return
有意义的数据,而不是改变内部状态。