【问题标题】:Why do JavaScript promises chain rejections into resolved promises?为什么 JavaScript 承诺将拒绝链接成已解决的承诺?
【发布时间】:2017-06-02 20:04:54
【问题描述】:

我想知道为什么拒绝与 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);
});

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

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

为什么 Promise 的链接会将拒绝变为成功的解决?

编辑:我想澄清一下这个问题有实际应用。

如果您想使用链接将数据从 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);
 });

【问题讨论】:

  • ... 因为... 这就是它的作用?这就是它的设计方式。
  • 我相信将第二个回调添加到 .then() 会捕获拒绝
  • 我喜欢有人否决了这个问题和所有答案。他真的很讨厌这个帖子!
  • 您的编辑...不正确。这将导致未经处理的拒绝。 // some code elsewhere 必须与它交互。
  • 例如,假设您想从服务器获取数据。数据不是页面操作所必需的,但您希望等到拥有数据(或检索数据失败)后再执行操作 A。使用 .then() 错误回调将允许您将从服务器获取数据的失败转换为没有数据的成功,然后您可以继续链接,这意味着在它必须关心服务器是否响应失败或它是否成功响应但没有数据.它只会根据您提供的数据采取行动。

标签: javascript promise


【解决方案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】:

    MDN documentation for Promise.prototype.then 说:

    在调用处理函数[传递给then()的函数]后,then返回的promise被解析为返回值。

    【讨论】:

      【解决方案3】:

      它旨在让您从承诺链中的错误中优雅地恢复。

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

      【讨论】:

      • 链接时如何传播拒绝?
      • 你将一个被拒绝的承诺返回给拒绝处理程序(或者根本不处理它)
      • 您可以在拒绝处理程序中再次抛出
      【解决方案4】:

      这与 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!");
      });
      

      【讨论】:

        猜你喜欢
        • 2023-03-26
        • 2019-08-06
        • 1970-01-01
        • 2019-11-25
        • 2013-06-22
        • 1970-01-01
        • 2013-09-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多