angular不等待承诺解决

时间:2016-11-23 20:44:45

标签: javascript angularjs q

我的问题是角度不等待承诺得到解决。 正如你在控制台的inspect中所看到的那样,它打印出它没有得到提供者和技能对象,而下面是承诺返回。

下面添加的是我认为最相关的代码部分。我使用angulars库创建了服务 - $ q并使用了deferred,then和when选项 - 如下面的服务中所示。

提供商服务:

this.getProviderById = function (providersId) {
        // will hold backend provider of the provider with id = providersId
        var provider = undefined;
        // if provider object is not defined then start the new process to fetch it
        if (!provider) {
            // create deferred object using $q
            var deferred = $q.defer();

            // get provider form backend
            $http.get('http://localhost:3000/providers/getbyid/' + providersId)
                .then(function (result) {
                    console.log('provider by id result - ' + JSON.stringify(result.data));
                    // save fetched provider to the local variable
                    provider = result.data;
                    // resolve the deferred
                    deferred.resolve(provider);
                }, function (error) {
                    providers = error;
                    deferred.reject(error);
                });

            // set the provider object to be a promise until result comeback
            provider = deferred.promise;
        }
        return $q.when(provider);
    };

提供者控制器定义:

 var vm = this;
    vm.getCurrentUser = getCurrentUser;
    function getCurrentUser(){
        console.log('returning current user from auth service');
        return authService.getCurrentUser();
    }
    vm.getProviderById = getProviderById;
    function getProviderById(providersId){
        providerService.getProviderById(providersId)
            .then(function onSuccess(providerResult){
                console.log('providerResult - ' + JSON.stringify(providerResult));
                $scope.provider =  providerResult;
            }, function onError(error){
                console.log('error getting provider by id - ' + error);
            });
    }

    vm.getProviderSkills = getProviderSkills;
    function getProviderSkills(providersId){
        providerService.getProvidersSkills(providersId).then(function onSuccess(resultSkills){
            console.log('resultSkills - ' + JSON.stringify(resultSkills));
            $scope.skills = resultSkills;
        }, function onError(error){
            console.log('error getting providers - ' + $scope.provider + ' - skills');
        });
    }

提供者控制器使用:

  $scope.user = vm.getCurrentUser();
    if ($scope.user !== null && $scope.user !== undefined) {
        console.log('user - ' + JSON.stringify($scope.user));
    } else {
        vm.initUsersProvider();
        console.log('initiated users provider');
    }
    vm.getProviderById($scope.user.provider);
    if ($scope.provider !== null && $scope.provider !== undefined) {
        console.log('provider - ' + JSON.stringify($scope.provider));
    } else {
        console.log('didnt get provider object');
    }
    vm.getProviderSkills($scope.provider);
    if ($scope.skills !== null && $scope.skills !== undefined) {
        console.log('provider - ' + JSON.stringify($scope.skills));
    } else {
        console.log('didnt get skills object');
    }

检查控制台显示上图的结果:

user - {"_id":"5835b06b975ace23244bf205","email":"iairbluer@gmail.com","password":"","fbuser":"5835b06a975ace23244bf204","provider":"5835b06f975ace23244bf206","admin":false,"__v":0}
ProviderRegisterController.js:14 providersId - 5835b06f975ace23244bf206
providerService.js:74 providersId - 5835b06f975ace23244bf206
ProviderRegisterController.js:110 didnt get provider object
ProviderRegisterController.js:117 didnt get skills object
ProviderRegisterController.js:122 no availability module found
ProviderRegisterController.js:124 no bio module found
providerService.js:83 provider by id result - {"_id":"5835b06f975ace23244bf206","bio":"","__v":2,"references":[],"availability":{"auto":true},"skills":["5835b220975ace23244bf208","5835b2ff975ace23244bf209"]}
ProviderRegisterController.js:17 providerResult - {"_id":"5835b06f975ace23244bf206","bio":"","__v":2,"references":[],"availability":{"auto":true},"skills":["5835b220975ace23244bf208","5835b2ff975ace23244bf209"]}
providerService.js:56 received skills from db - [object Object],[object Object]
ProviderRegisterController.js:27 resultSkills - [{"_id":"5835b220975ace23244bf208","topic":2,"description":"sdfsdf","price":45,"status":"PENDING","__v":0},{"_id":"5835b2ff975ace23244bf209","topic":1,"description":"ddfgdfg","price":45,"status":"PENDING","__v":0}]

感谢所有帮助:)

2 个答案:

答案 0 :(得分:2)

问题在于,当您调用函数vm.getProviderByIdvm.getProviderSkills时,它们会调用其他返回promise的函数,但这些函数本身不会。因此,他们被调用,然后继续下一步。

如果这些功能确实相互依赖,则需要将承诺链接在一起,或者从各自承诺的success内部调用它们。

答案 1 :(得分:0)

在提供者控制器使用中:

$scope.user = vm.getCurrentUser();
if ($scope.user !== null && $scope.user !== undefined) {
    console.log('user - ' + JSON.stringify($scope.user));
} else {
    vm.initUsersProvider();
    console.log('initiated users provider');
}
vm.getProviderById($scope.user.provider);
if ($scope.provider !== null && $scope.provider !== undefined) {
    console.log('provider - ' + JSON.stringify($scope.provider));
} else {
    console.log('didnt get provider object');
}
vm.getProviderSkills($scope.provider);
if ($scope.skills !== null && $scope.skills !== undefined) {
    console.log('provider - ' + JSON.stringify($scope.skills));
} else {
    console.log('didnt get skills object');
}

当对vm.getProviderId()的调用返回时,您唯一可以确定的是.then()中的vm.getProviderId()代码尚未被调用。但是,您尝试访问$scope.provider并且它将不会被设置。

getProviderId必须返回Promise以指示它何时完成。如果需要,您还可以使用provider解决承诺(这可能比分配到此处的范围更好)。

vm.getProviderById = getProviderById;

function getProviderById(providersId){
    return providerService.getProviderById(providersId)
        .then(function onSuccess(providerResult){
            console.log('providerResult - ' + JSON.stringify(providerResult));
            return provider;
        }, function onError(error){
            console.log('error getting provider by id - ' + error);
        });
}

以类似的方式更改getProviderSkills()以返回最终承诺。

现在你这样使用它:

vm.getProviderById($scope.user.provider)
.then(function(provider) {
    $scope.provider = provider; // If you still need to save it in scope.
    if (provider !== null && provider !== undefined) {
        console.log('provider - ' + JSON.stringify(provider));
    } else {
        return $q.reject('didnt get provider object');
    }
    return vm.getProviderSkills(provider);
})
.then(function(skills) {
    if (skills === null || skills === undefined) {
        return $q.reject('didn\'t get skills object');
    }
    $scope.skills = skills;
},
function failureCallback(error) {
    console.log(error);
});

请注意,通过返回$ q.reject(),您可以中止序列的其余部分,并在末尾有一个位置来处理/记录错误。