中继Q承诺结果到另一个承诺

Relay Q promise results to another promise

本文关键字:一个承诺 结果 承诺 中继      更新时间:2023-09-26

我将Q与RequireJS一起使用。我经常发现自己写这样的代码:

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链的结果传递给外部deferred/promise。

我知道我可以用这样的承诺来解决

res.resolve( 
      mod().then( function(){
            // ...
            return somePromise;
          })
    );

但是当链变长或包含更多代码时,这将很难读懂。

我基本上是在寻找一种方法/方式来做这样的事情:

mod().then( function(){
      // ...
      return somePromise;
    })
    .relay( res );

这相当于上面的代码,用于在承诺链中维护错误。

我已经研究了Q.nfcall()Q.nfapply(),但这些只适用于回调,它必须参数errorresult。然而,在require()调用的情况下,参数是被请求的模块,它不符合Q想要拥有的签名…

关键是您不应该在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;
});

将一个承诺"中继"到一个等待它的递延对象中,基本上是使用反向符号的递延反模式。注意,如果您真的需要这样一个方法,它看起来就像

Promise.prototype.relay = function(def) {
    return def.resolve(this);
};