2015-11-06 70 views
0

我在想以下是否为正常行为?何时 - 出现中间错误的意外承诺链

代码

var when = require('when'); // I'm using [email protected] node_modules/when 

console.log("INIT"); 

when.promise(function(resolve, reject) { 
    return when.reject("false") 
    .then(function(ok) { 
     console.log("Step 1 - in then, ok = %s", ok); 
     return 'ok1'; 
    }, function(err) { 
     console.log("Step 1.1 - in catch, err = %s", err); 
     return reject(err); 
    }).then(function(ok) { 
     console.log("Step 2 - in then, ok2 = %s", ok); 
     return resolve("done"); 
    }).catch(function(err) { 
     console.log("Step 3 - in catch, err = %s", err); 
     return reject(err); 
    }); 
}).then(function(mainok) { 
    console.log("Step 9 - in main then, mainok = %s", mainok); 
}).catch(function(err) { 
    console.log("Step 9 - in main catch, err = %s", err); 
}); 

这是我收到的输出运行它

INIT 
Step 1.1 - in catch, err = false 
Step 2 - in then, ok2 = undefined 
Step 9 - in main catch, err = false 

当读API我期待这一步骤1.1将被调用,那么第9步而不是第2步。

这是一个错误还是我误读了API?

感谢您的提示!

+1

请注意[反模式](https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns)(创建不必要的承诺时,您可以使用/返回已有的)。 – jfriend00

+0

避免['Promise'构造函数反模式](http://stackoverflow.com/q/23803743/1048572)! – Bergi

回答

0

是的,这是预期的行为。下面是我看到的步骤:

  1. 您创建等待resolve()reject()被称为它的外部承诺。
  2. 然后,您创建一个开始拒绝的内部承诺。
  3. 然后,它会转到第一个处理程序的第二个处理程序(例如拒绝处理程序),您会看到“步骤1.1”输出。
  4. 1.1处理程序然后拒绝外部承诺,但处理继续在内部的承诺。
  5. 因为您有一个.then()拒绝内部承诺的处理程序,并且您没有丢弃或返回该处理程序拒绝的承诺,所以内部承诺的状态切换为解决。如果你“处理”了被拒绝的承诺,并且不抛弃或返回被拒绝的承诺,那么状态切换到履行。
  6. 因此,被调用的下一个.then()处理程序是“步骤2”,因为承诺现在已满足,而不是被拒绝。
  7. 解析处理程序然后调用resolve("done"),但外部承诺已被拒绝尝试resolve()它现在什么都不做。它的状态已经设定,不能改变。
  8. 由于内部承诺现在已满足,它跳过了“步骤3”.catch()处理程序。
  9. 外面的承诺早些时候被拒绝了,所以它跳过了“步骤9”.then()履行的处理程序,并且最后的.catch()处理程序“第9步 - 在主要的catch”中。

请记住,所有承诺都是异步解决或拒绝的。对外承诺调用reject()不会立即运行外承诺的.catch()处理程序。它安排它在未来运行。

+0

非常有用的感谢。那么以我的方式使用内部承诺是否合法?或者我宁愿使用Promise组合器,如.all或.join(或类似的)? – Boris

+0

@Boris:你绝对应该使用combinators,几乎从不使用'when.promise'构造函数 – Bergi

+0

@Bergi感谢您的帮助 – Boris