我和RequireJS一起使用Q.我经常发现自己编写这样的代码:
function someFunc() {
// prepare result
var res = Q.defer();
require( ['someOtherModule'], function( mod ) {
// do some stuff with mod
mod().then( function(){
// ...
return somePromise;
})
.then( function( val ) {
// resolve the functions deferred
res.resolve( val );
}, function( err ){
// relay error
res.reject( err );
});
});
// return promise
return res.promise;
}
所以我有一个函数someFunc()
,它请求一个模块(它可以在运行时确定要加载哪个模块),然后用该模块做一些可能使用promise链本身的东西(在这个例子中只有一个)链中的元素,但可以更多)。
最后,我只想将内部承诺链的结果转发给外部延期/承诺。
我知道我可以解决承诺本身就像这样
res.resolve(
mod().then( function(){
// ...
return somePromise;
})
);
但是当链条变长或包含更多代码时,这将难以理解。
我基本上正在寻找一种方法/方法来做这样的事情:
mod().then( function(){
// ...
return somePromise;
})
.relay( res );
这相当于保留承诺链中的错误的上述代码。
我已经查看了Q.nfcall()
或Q.nfapply()
,但这些仅适用于回调,其中包含参数error
和result
。但是,在require()
调用的情况下,参数是请求的模块,它不符合Q想要拥有的签名...
答案 0 :(得分:2)
关键是你不应该将你的链嵌套在require
回调中。在最低级别实现承诺:
function requirePromise(dep) {
var res = Q.defer();
require([dep], function(mod) {
res.resolve(mod);
});
return res.promise;
}
然后你可以在平链中使用它,如你所愿:
requirePromise('someOtherModule').then(function(mod) {
…
return somePromise;
});
将“承诺”转换为等待它的延迟,基本上是带有反转符号的deferred antipattern。请注意,如果您真的想要这样的方法,它就像
Promise.prototype.relay = function(def) {
return def.resolve(this);
};