Javascript 为什么deferred.resolve的行为不符合q手册中的规定?

Javascript 为什么deferred.resolve的行为不符合q手册中的规定?,javascript,node.js,q,Javascript,Node.js,Q,这可能是一个愚蠢的问题,但我无法理解这一点 考虑以下代码: function throwError() { throw Error("can't touch this."); } var def = q.defer(); def.promise.then( function() { console.log("no error"); }, function() { console.log("error"); } ); q.fcall(throwErro

这可能是一个愚蠢的问题,但我无法理解这一点

考虑以下代码:

function throwError() {
    throw Error("can't touch this.");
}

var def = q.defer();

def.promise.then(
  function() {
    console.log("no error");
  },
  function() {
    console.log("error");
  }
);

q.fcall(throwError).then(def.resolve, def.resolve).done();
我认为这应该打印
错误
。而是打印
无错误
q
手册说明:

reject函数是用rejected进行解析的简写 答应我

q.fcall(throwError)
应该产生一个被拒绝的承诺,所以延迟的承诺应该被拒绝,对吗


请注意,这是一个纯粹的假设性问题,我知道这不会在现实世界中使用。

这里的问题似乎与所使用的语言有关,因此我将尝试将其进一步细分以使其更清楚。当你打电话的时候

var rejected = q.fcall(throwError);
那么,
被拒绝
确实是被拒绝的承诺。你现在做的是

var def = q.defer();
def.promise.then(
  function(arg1) {
    console.log("no error");
  },
  function(arg2) {
    console.log("error");
  }
);

rejected.then(
  function(){
    def.resolve();
  },
  function(err){
    def.resolve(err); // err === new Error();
  }
);
当承诺被拒绝时,它将运行拒绝回调,触发
def.resolve(err)。Q不知道
def
是一些随机片段以外的任何东西,所以您最好调用
def.resolve('random')。您正在使用一些参数解析
def
。在这种情况下,它恰好是
错误的一个实例。这意味着将调用
no error
回调,并且
arg1===new error()

现在,根据您提到的文档报价

拒绝函数是用拒绝的承诺进行解析的简写

您所做的基本上是将被拒绝的承诺
rejected
转换为承诺
def.promise
,该承诺将始终得到履行,但履行处理程序将收到一个错误作为第一个参数

为了实现您的期望,您需要正确地拒绝
def.promise
。您可以通过两种方式实现这一点

  • 使用
    def.Reject(错误)拒绝它
  • 正如你的报价所说,用拒绝的承诺来解决它,
    def.resolve(拒绝)

  • 实际上,我想使用
    def.resolve
    两次。如上所述,用拒绝的承诺解决问题应该触发错误处理程序,而不是实现处理程序。因此,在我看来,应该调用第二个函数,而不是第一个。@raffomania抱歉,下面没有
    q.fcall(throwError)
    确实会产生一个被拒绝的承诺,正如您所说,但是由于您已经通过了
    def.resolve
    作为错误处理程序,它将在没有错误的情况下解析
    def
    ,就像调用
    def.resolve()一样
    其他地方。可能混淆的地方是
    使用拒绝的承诺解决问题。
    您现在所做的是使用
    错误对象解决问题,而不是使用拒绝的承诺解决问题。请查看此处:。在那里你可以看到我的例子
    q.fcall
    应该产生一个被拒绝的承诺,而不是一个错误。@raffomania Correct,
    fcall
    的返回值返回一个被拒绝的承诺。然后调用
    .Then
    ,它提取与拒绝相关的错误,并将该错误作为第一个参数传递。我将扩展我的答案。