为什么JavaScript承诺将链排斥到已解决的承诺中?

时间:2017-06-02 20:04:54

标签: javascript promise

我想知道为什么拒绝链接被ES6承诺解决了?

以下是一个例子:

let p = Promise.reject().then(function () {
    return 'one';
}, function() {
    return 'two';
});

p.then(function (value) {
   // I do not expect this to be executed, since it was not resolved.
   console.log(value);
});

以上输出“2”到控制台。

https://jsfiddle.net/pscb88xg/1/

为什么承诺的链接会将拒绝变成成功的决心?

编辑:我想澄清一下这个问题是否具有实际应用效果。

如果您想使用链接将数据从A转换为B,该怎么办?

 p.then(function (A) {
     return new B(A);
 });

上述内容将拒绝变为已解决的值。即使没有使用拒绝回调。

例如;

 let p = Promise.reject('error').then(function (A) {
      return new B(A);
 });

 // some code elsewhere

 p.then(function (B) {
      console.log('success!');
 });

在上面的例子中。值 B 不是B而是错误,并且稍后在链中成功解析。

这是正常的吗?

编辑:我现在理解我的困惑。我在这样的拒绝中提取HTTP标头值。

 let p = myHttpService.get(...).then(function() {
          //....
 }, function(response) {
          // get headers
 });

以上是将我的承诺链接到一个已解决的价值,我不明白为什么。我可以用以下内容修复我的代码。

 let p = myHttpService.get(...).then(function() {
          //....
 }, function(response) {
          // get headers
          return Promise.reject(response);
 });

4 个答案:

答案 0 :(得分:1)

这意味着您可以优雅地从承诺链中的错误中恢复。

示例可能是来自服务器的304 Not Modified响应。如果您使用基于承诺的库来执行http请求,则任何不是2XX的响应都将被视为失败,并且承诺将被拒绝。从应用程序的角度来看,304可能和200一样好,你想继续正常。

答案 1 :(得分:1)

在处理错误之后,您通常希望代码继续运行,类似于catch块之后的代码运行方式正常,而未捕获的异常会中止。

如果你想中止而不是在链的末尾处理错误:

let p = Promise.reject().then(function () {
    return 'one';
});

p.then(function (value) {
   // This won't run, because the rejection hasn't been handled yet
   console.log(value);
}, function() {
   return console.log( 'there was a problem' );
}).then(function ( ) {
   // This will run because the rejection has been dealt with already.
   console.log( 'Moving on');
});

答案 2 :(得分:1)

MDN documentation for Promise.prototype.then说:

  

在调用处理函数[传递给then()]的函数之后,then返回的承诺将以返回的值作为其值进行解析。

答案 3 :(得分:0)

这与AngularJS的$q提供商的行为相同。

发生突变是因为在您的拒绝处理程序中,您返回的是值而不是被拒绝的承诺。如果您反而传递被拒绝的承诺,它将表现出您的期望:

let p = Promise.reject().then(function () {
    return 'one';
}, function() {
    return Promise.reject('two');
});

p.then(function (value) {
   // I do not expect this to be executed, since it was not resolved.
   console.log(value);
}, function() {
  console.log("Rejected, baby!");
});