【问题标题】:Function return doesn't wait for angularjs promises函数返回不等待 angularjs 承诺
【发布时间】:2014-08-19 22:45:04
【问题描述】:

我对 angularjs 的承诺有疑问,也许有人可以指出我正确的方向。我的控制器中有一个验证函数,如果一切正常,它应该返回 true,如果有问题,则返回 false。单页应用程序在这个假设下工作,所以我不能轻易改变这个假设......

window.customerValidation = function ($scope, $rootScope, $alert, $q) {
        var isValidated = false;


        if (!$scope.scopeData.customer.nationalId && !$scope.scopeData.customer.passportNumber && !$scope.scopeData.customer.driverLicenseNumber) {
            $alert.error("Please enter at least one identification info.");
            return false;
        }


        $scope.scopeData.customer.checkForDuplicateIdentity().then(function () {
            var customer = $scope.scopeData.customer;
            if (!customer.idValidated) {
                $alert.error(customer.idValidationMessage);
            }

            if (!customer.idValidated)
            {
                return false;
            }

            if ($scope.customerDataForm && $scope.customerDataForm.$error && $scope.customerDataForm.$error.required) {
                var missingFields = [];
                angular.forEach($scope.customerDataForm.$error.required, function (value, key) {
                    missingFields.push("-" + value.$name);
                });

                $alert.error("Please fill in the all required fields.\r\n" + missingFields.join("\r\n"));
            }
            else if ($scope.customerDataForm && $scope.customerDataForm.$error && $scope.customerDataForm.$error.email) {
                var invalidEmailFields = [];
                angular.forEach($scope.customerDataForm.$error.email, function (value, key) {
                    invalidEmailFields.push("-" + value.$name);
                });

                $alert.error("Please enter valid e-mail addresses.\r\n" + invalidEmailFields.join("\r\n"));
            }
            else if (!Date.parse($scope.scopeData.customer.dateOfBirth)) {
                $alert.error("Please enter a valid date for Date of Birth.");
            }
            else {
                $scope.scopeData.customer.updateIndividualCustomerInfoRequest();
                $scope.scopeData.customer.updateOrder();
                $rootScope.customerName = $scope.scopeData.customer.firstName + " " + $scope.scopeData.customer.lastName;
                isValidated = true;
            }

        });

        return isValidated;


    };

在最近需求发生变化之前一切正常,我正在尝试检查服务器以查看之前系统中是否使用过 id 值。因此我必须对服务器进行异步调用并检查它,你可以看到我使用了 $scope.scopeData.customer.checkForDuplicateIdentity() 方法并承诺让异步调用工作。

调用工作正常我测试过,唯一的问题是我的 customerValidation 方法在异步调用完成之前完成并一直返回 false。也就是说

return isValidated 行总是在 isValidated 变为真之前执行。

我无法让外部 return 语句等待异步调用完成。如果我从内部函数返回 isValidated,它不会将值返回给 customerValidation 函数。有人可以告诉我如何实现这一目标吗?

【问题讨论】:

  • 返回承诺而不是布尔值。
  • 你的意思是我应该在customerValidation函数中返回promise?
  • 你是通过什么方式使用这个功能的?
  • 验证方法被调用,返回值是否为真,显示下一个控制器视图。如果它是假的,错误消息被警告,显示没有任何变化。执行代码是通用的,适用于 6-7 个控制器,因此更改它并不容易,它期望返回一个布尔值

标签: javascript angularjs angular-promise


【解决方案1】:

调用异步函数的函数本身必须是异步函数。更改 window.customerValidation 使其返回一个承诺。

  • 删除var isValidated = false;
  • 在第 7 行将 return false 替换为 return $q.reject()
  • $scope.scopeData.customer.checkForDuplicateIdentity()前面添加return
  • 在你给then的回调中,当验证通过时return,当验证失败时throw一个错误

然后在window.customerValidation的调用者中替换

if (window.customerValidation()) {
    // validation passed
} else {
    // validation failed
}

通过

window.customerValidation()
    .then(function () {
        // validation passed
    })
    .catch(function (error) {
        // validation failed
    })

【讨论】:

    【解决方案2】:

    你可以随时使用javascript提供的超时功能,比如

    setTimeout(function {DO_SOMETHING}, 50);
    

    这将在调用函数之前等待 50 毫秒。这样您就可以等待异步调用完成。

    希望这会有所帮助。

    【讨论】:

    • 我也想过,但这会让事情变得完全不确定,如果请求由于负载过重需要 1000 毫秒来处理怎么办。
    • 没错,但仍然如此。我遇到了同样的问题,这是我能想出的唯一解决方案……而且效果很好(因为我的通话最多只需要 0-10 毫秒)。
    • 值得一提的是同样的问题,return isValidated 会在 DO_SOMETHING 执行之前执行。
    • 这总是取决于已设置的超时。在这种情况下,我将 50 毫秒设置为超时。如果异步调用的完成时间超过 50 毫秒,isValidated 会在之前返回。我试图为您的问题找到更好的答案,并发现您可以使用 Promise。在此处阅读有关它的更多信息(解释得非常好)Click here to read more
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 2017-10-17
    • 1970-01-01
    相关资源
    最近更新 更多