首页 > 解决方案 > 如何检查角度承诺的状态?

问题描述

在我的网站中,我有用于 twitter 和 facebook 的 API,它启用了“提及”功能(每当我们使用 @ 符号时就会弹出该功能)

但是,某些功能的访问令牌通常会过期,从而导致 API 无法正常工作。我将所有 API 存储在一个数组中,然后我需要检查令牌是否失败或没有导致解决或拒绝 API 承诺。

这是一个较旧的代码,由于 $q.all 需要更改。由于 $q.all 会在所有承诺都得到解决时起作用,从而触发 .then() 调用,这导致 .then() 函数在我的情况下永远不会工作(因为 Facebook API 永远不会工作)

我需要找到一个条件,检查每个 API 并且 .then() 仅针对已解析的 API(在本例中为 Twitter)运行并忽略失败的 API(在本例中为 Facebook)


        if (selectedIds.allowed.TW) {
          usersApi.push(TS.loginResource.getTwitterProfiles({
            subUserId: selectedIds.allowed.TW,
            name: searchTerm
          }).$promise);
        }

        if (selectedIds.allowed.FB || selectedIds.allowed.FB_PAGE || 
            selectedIds.allowed.FB_GROUP) {
          $scope.post.showTags = true;
          usersApi.push(TS.loginResource.getFbPages({
            subUserId: selectedIds.allowed.FB_PAGE || selectedIds.allowed.FB 
            || selectedIds.allowed.FB_GROUP,
            name: searchTerm
          }).$promise);
        }


        if (usersApi.length) {
          $q.all(usersApi).then(function (responses) {
            var tags1 = responses[0];
            tags1.forEach(function (tag, i) {
              tags1[i].name = tag.name.replace(/\"/g, "");
            });
            $scope.post.tags = tags1;
            if (usersApi.length > 1) {
              var tags2 = responses[1]
              tags2.forEach(function (tag, i) {
                tags2[i].name = tag.name.replace(/\"/g, "");
              });
              $scope.post.tags = $scope.post.tags.concat(tags2);
            }
          })
        }
      }, 500);
    } else {
      $scope.post.tags = [];
      $scope.post.showTags = false;
    }

标签: angularjsangular-promise

解决方案


$q.all没有弹性1

如果其中一个 promise 被拒绝,$q.all则第一个错误被拒绝。

要创建一个有弹性的复合 Promise,即等待所有 Promise 完成通过或失败的 Promise,请.catch在每个单独的 Promise 上使用被拒绝的 Promise 转换为成功的 Promise。

var resilientPromises = [];

angular.forEach(promises, function(p) {
    var resilientP = p.catch( function(result) {
        //return to convert rejection to success
        return result;
    });
    resilientPromises.push(resilientP);
});

$q.all(resilientPromises).then( function (results) {
    //process results
});

从这个答案中可以看出两点:

  1. 一个$q.all承诺是没有弹性的。它被第一个被拒绝的承诺拒绝。
  2. 通过将值返回.then给方法或方法的 onRejected 函数,可以从被拒绝的 Promise 中创建已履行的 Promise .catch

推荐阅读