将 Q 承诺结果传递给另一个承诺

Relay Q promise results to another promise

我将 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(),它请求一个模块(它可能在运行时确定要加载哪个模块),然后可能使用承诺链本身(在示例中)对该模块做一些事情链中只有一个元素,但可以有更多)。

最后我只是想将我内部承诺链的结果传递给外部deferred/promise。

我知道我可以像这样用承诺本身来解决

res.resolve( 
      mod().then( function(){

            // ...
            return somePromise;

          })
    );

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

我基本上是在寻找 method/way 来做这样的事情:

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;
});

"Relaying" 一个真正等待它的延迟的承诺基本上是 deferred antipattern 与倒置符号。请注意,如果您真的想要这样的方法,它看起来就像

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