在服务中等待 Angular JS(REST -> $resource)

Await Angular JS in a service (REST -> $resource)

本文关键字:resource REST 服务 等待 Angular JS      更新时间:2023-09-26

互联网上有很多关于这个话题的话题。但我仍然被困住了。由于所有的信息,我再也看不到森林里的三人了(荷兰语)

希望以这种方式得到一些帮助。如果这是重复的,我真的很抱歉!我主要是一名C#开发人员,但想学习一些Web框架。我开始@ AngularJS。这是我的第一个大项目。所以我在AngularJS方面仍然是

新手

我正在制作一种 DAL(是的 C#)。我为此使用服务。我的目的当然是封装其余的控制器调用!

angular.module("adminApp").service("adminRestDAL", function ($resource, $q) {
var userData;
this.getUsers = function () {
    if (!userData)
        userData = $resource("/admin/users").query();
    return userData;
};

所以这是我获取所有用户的功能。我使用了"缓存",我没有重新加载所有用户。在我的应用程序中不需要它。结果它更流畅!(减少等待)

现在我的问题是我想加载我所有的答案。我借助他们的用户ID将用户名添加到我的答案中。我想使用我的本地列表(缓存一个)...

this.getAnswers = function () {
    //Always update answers!
    //No need for manuel caching (no global variable)
    //Make sure we have our users loaded!
    //This is exactly why I <3 C#
    //I could reuse my existing function (getUsers) and just put 'await' before it...
    this.getUsers();
    var answersData = $resource("/admin/answers").query(function (data) {
        data.forEach(function (answer) {
            answer.name = userData.find(function (u) {
                return u._id === answer.userid;
            }).name;
        });
    });
    return answersData;
};

检查评论。我必须等到用户加载完毕才能继续。在 80% 的情况下,此功能有效。用户在答案之前完成,然后没有问题。但是当它不是时,用户数据是未定义的,我的答案将没有用户名......

我尝试了很多。这是我的最终解决方案(这行不通)。我做了一个单独的函数来返回查询的承诺

function getUsersAsync() {
    if (!userData)
        return $resource("/admin/users").query().$promise
            .then(
                function (success) {
                    userData = success;
                })
};
this.getAnswers = function () {
    //Always update answers!
    //No need for manuel caching (no global variable)
    //Make sure we have our users loaded!
    //This is exactly why I <3 C#
    //I could reuse my existing function (getUsers) and just put 'await' before it...
    //this.getUsers();
    getUsersAsync().then(
        function()
        {
            var answersData = $resource("/admin/answers").query(function (data) {
                data.forEach(function (answer) {
                    answer.name = userData.find(function (u) {
                        return u._id === answer.userid;
                    }).name;
                });
            });
            return answersData;
        }
    )
};

在这里,"代码"等到我的用户加载完毕。但是我无法再返回我的数据(答案)了!现在返回的是另一个函数,而不是我的 getAnswers() 函数...

所以我不知道如何在 AngularJS 中解决这个问题。我搜索了很多,找到了一些有用的博客。但仍然卡住了。我还发现 ES7 带有 Await 和 Async 关键字......

如果您有解决此问题或使其更好的提示。你真的会帮我的!

如果我的"架构"有问题,也请告诉我,就像我第一次在AngularJS中所说的那样。我想学习:)

真诚的,橡皮擦布莱希特

使用原始$promise并从中链接

this.getAnswers = function () {
    var answersData = $resource("/admin/answers").query();
    //save promise for chaining
    var secondPromise = answersData.$promise.then( function (data) {
        data.forEach(function (answer) {
            answer.name = userData.find(function (u) {
                return u._id === answer.userid;
            }).name;
        });
    });
    //return secondPromise for chaining    
    answersData.$promise2 = secondPromise;
    return answersData;
};

在客户端代码中,从第二个承诺链接。

var refinedAnswers = getAnswers();
refinedAnswers.$promise2.then (function onFulfilled() {
    console.log(refinedAnswers);
};

有关链接的更多信息,请参阅 AngularJS $q服务 API 参考 -- 链接。

不应尝试在服务中组合用户和应答数据。 该服务只是抓取数据的封装 - 它是应该组合数据的控制器,以便以有效的格式将其提供给您的视图。

考虑到这一点,您的服务应该很简单:

this.getUsers = function(){
    return $resource("/admin/users").query();
};
this.getAnswers = function(){
    return $resource("/admin/answers").query();
};

然后,在控制器中,您可以将缓存逻辑拼凑在一起。

$scope.users = null;
$scope.getUsers = function(){
    if($scope.users === null){
        myService.getUsers().$promise.then(function(data){
            $scope.users = data;
        });
    }
});
$scope.getAnswers = function(){
    myService.getAnswers().$promise.then(function(data){
        $scope.answers = data;
        for(var i = 0; i < $scope.answers.length; i++){
            $scope.answers[i].name = $scope.users.find(function(u){
                    return u._id === $scope.answers[i].userid;
            }).name;
        }
    });
});

当我向Stackoverflow发布一些东西时,我总是在几分钟后自己找到答案。我应该停顿一下。

我忘了尝试在我的getAnwsersers资源的回调中执行我的getUser功能。这确实解决了我的问题。

不过感谢回答的两个人!这就是为什么stackoverflow对于正在学习东西的新人来说是一个好地方的原因:)

//Private function
//Had to do this because if need to access this function inside a callback
//this doesn't point to this service anymore but to the callback...
function getUsersAsync() {
    if (!userData)
        userData = $resource("/admin/users").query();
    return userData;
};
this.getUsers = function () {
    return getUsersAsync();
};
this.getAnswers = function () {
    //Always update answers!
    //No need for manuel caching (no global variable)
    var answersData = $resource("/admin/answers").query(function (data) {
        //Make sure we have our users loaded!
        getUsersAsync().$promise
            .then(
                function () {
                    data.forEach(function (answer) {
                        answer.name = userData.find(function (u) {
                            return u._id === answer.userid;
                        }).name;
                    });
                }
            )
    });
    return answersData;
};