继承Q承诺导致另一个承诺

时间:2015-08-17 09:53:53

标签: javascript requirejs q

我和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(),但这些仅适用于回调,其中包含参数errorresult。但是,在require()调用的情况下,参数是请求的模块,它不符合Q想要拥有的签名...

1 个答案:

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