Как проверить состояние углового обещания? - PullRequest
0 голосов
/ 15 июня 2019

На моем веб-сайте у меня есть API для твиттера и фейсбука, который включает функцию «упоминаний» (которая появляется, когда мы используем символ @)

Однако часто токен доступа к какой-либо функции часто истекает, в результате чего API не работает. Я храню все свои API в массиве, а затем мне нужно проверить, не прошел ли токен или нет, что привело к разрешению или отклонению обещания API.

Это старый код, который нужно изменить из-за $ q.all. Поскольку $ q.all работает всякий раз, когда все обещания были разрешены, вызывая, таким образом, вызов .then (), это приводит к тому, что функция .then () НИКОГДА не работает в моем случае (так как API Facebook никогда не работает)

Мне нужно найти условие, при котором проверяется каждый 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;
    }

Ответы [ 2 ]

1 голос
/ 15 июня 2019

$q.all является не устойчивым 1

Если одно из обещаний отклонено, $q.all отклоняется с первой ошибкой.

Чтобы создать устойчивое составное обещание , то есть обещание, которое ожидает выполнения всех обещаний, чтобы выполнить или не выполнить, используйте .catch в каждом отдельном обещании, чтобы преобразовать отклоненное отклонение обещание успешного обещания.

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. A $q.all обещание не устойчиво . Это отклонено с первым отклоненным обещанием.
  2. Выполненное обещание может быть создано из отклоненного обещания путем возврата значения в функцию onRejected либо метода .then, либо метода .catch.
1 голос
/ 15 июня 2019

Я думаю, что вы ищете цепочечный ответ резервного копирования, который улавливает ошибку API и возвращает новое обещание успешного завершения при каждом конкретном вызове API, прежде чем вы дождетесь "всех" из них.

apiCalls.push(doTwiterStuff().then(handleTwiterSuccess, handleApiFailure);
apiClass.push(doFBStuff().then(handleFbSuccess, handleApiFailure);

Promise.all(apiCalls).then(arr => {
  arr.filter(x => !isNil(x)).forEach(x => doSomethingWithApiResult(x));
});

function handleApiFailure(x) {
  ...
  return Promise.resolve(null);
}

Надеемся на этопомогает.

...