Angular $q 全部结算

Angular $q Settle all

我正在学习 Angular 并创建一个服务以在此过程中处理 SharePoint 数据。我现在有一个更新 SharePoint 项目的功能,但我遇到了问题。如果调用该函数并在尝试更新项目时遇到错误,则所有项目都会完成更新,但只会调用第一个拒绝(失败的项目)。如果任何其他项目失败,则不会为它们调用拒绝。我希望能够将生成的所有错误推送到一个数组中,我可以将该数组传回给用户,以便他们可以处理所有错误。下面是我的代码:

this.UpdateListItems = function (webUrl, listName, itemsJson) {
    var deferred = $q.defer();
    var promises = [];

    angular.forEach(itemsJson, function (itemProps) {
        var itemPromise = this.UpdateListItem(webUrl, listName, itemProps.Id, itemProps)
            .then(function (response) {
                return deferred.resolve(response);
            }, function (error) {
                return deferred.reject(error);
            });
        promises.push(itemPromise)
    }, this);

    return $q.all(promises)
        .then(function (data) {
            return lists[listName];
        }, function () {
            console.info("Promises: " + JSON.stringify(promises));
            return $q.reject(promises);
        });
};

这里还有 JSON 返回的承诺。您将看到返回 4 个 promise 对象,前 2 个处于待处理状态(它们成功),然后第三个失败,因为服务器上不存在该项目。最后,第四个也应该因为与第三个相同的原因而失败,但是当第一个失败并且不处理任何进一步被拒绝的项目时,您可以立即看到拒绝 returns:

[
  {
    "$$state": {
      "status": 0,
      "pending": [
        [
          {
            "promise": {
              "$$state": {
                "status": 0
              }
            }
          },
          null,
          null,
          null
        ]
      ]
    }
  },
  {
    "$$state": {
      "status": 0,
      "pending": [
        [
          {
            "promise": {
              "$$state": {
                "status": 0
              }
            }
          },
          null,
          null,
          null
        ]
      ]
    }
  },
  {
    "$$state": {
      "status": 2,
      "value": {
        "data": {
          "error": {
            "code": "",
            "message": {
              "lang": "en-US",
              "value": "Resource not found for the segment 'TestList'."
            }
          }
        },
        "status": 404,
        "config": {
          "method": "GET",
          "transformRequest": [
            null
          ],
          "transformResponse": [
            null
          ],
          "url": "http://kl-sp10dev04/sites/angular/_vti_bin/listdata.svc/TestList(126)",
          "processData": false,
          "headers": {
            "Accept": "application/json;odata=verbose"
          }
        },
        "statusText": "Not Found"
      },
      "processScheduled": false
    }
  },
  {
    "$$state": {
      "status": 0,
      "pending": [
        [
          {
            "promise": {
              "$$state": {
                "status": 0
              }
            }
          },
          null,
          null,
          null
        ]
      ]
    }
  }
]

对于以后遇到此问题的任何人,这里就是答案。这是我现在使用的代码,它按预期工作。这就是 returns 一个等待所有项目承诺完成的承诺。如果所有项目都成功更新,那么它将通过返回对 JSON 对象列表的引用来解决。如果任何项目未能更新,它会拒绝将所有错误返回给用户进行错误处理的数组。请注意,Lists 数组是服务的 属性,因此您不会在此处看到它的定义。

this.UpdateListItems = function (webUrl, listName, itemsJson) {
    var promises = [];
    var errors = [];
    angular.forEach(itemsJson, function (itemProps) {
        promises.push(this.UpdateListItem(webUrl, listName, itemProps.Id, itemProps)
            .then(function (response) {
                return itemsJson[listName];
            }, function (error) {
                errors.push(error);
            }));
    }, this);
    return $q.all(promises)
        .then(function () {
            if (errors.length > 0) {
                return $q.reject(errors);
            }
            else {
                return lists[listName]
            }
        });
};

社区要求允许 $q.all() 在一个失败后继续,但 Angular 没有实现。有些人写了一些 $q 额外内容,例如 this one.

在copy/paste之后,您需要在代码中引用'angular-q-extras'模块并调用

  $q.allSettled(promises).then(results => ...//some fails, some not )

现在你可以