【问题标题】:Http service delay processing until after data is returnedHttp服务延迟处理直到数据返回后
【发布时间】:2017-08-03 16:06:03
【问题描述】:

我从事我的 angularjs 项目。 我创建了这个服务:

(function () {
    "use strict";

    angular.module("manageItems").factory("manageItemsService", ["$http", "config", manageItemsService]);

    function manageItemsService($http, config) {
        var service = {
            getNewItems: getNewItems,
        };
        return service;

        function getNewItems(session, mapName) {
            return $http.get(serviceUrl + 'getNewItems/' + session + "/" + mapName);
        }

    }
})();

这里是我如何从控制器调用服务:

function getNewItems() {
    manageItemsService.getNewItems(mapguideService.mapName, mapguideService.sessionId).then(function (result) {
        self.currentItems = result.data;
    })
}

我需要在响应返回时延迟服务。

如何更改 servicefunction 以使其等到 self.currentItems 属性被数据填充?

【问题讨论】:

  • 这是预期的行为,但问题是什么??
  • @PankajParkar 请查看更新
  • 我可以知道确切的场景是什么吗??
  • 从 getNewItems() 返回一个承诺
  • @PankajParkar 服务被触发,我需要等待数据。如果响应为空,我需要触发另一个服务。但只有在我检查第一个调用是否为空之后。

标签: angularjs angular-promise angularjs-service angularjs-http


【解决方案1】:

那么你可以在getNewItems $http 电话上拨打.then。并根据检索到的响应数据,决定是返回数据还是调用其他服务方法。

function anotherFunction(){
    return $http.get(url);
}

function getNewItems(session, mapName) {
    return $http.get(serviceUrl + 'getNewItems/' + session + "/" + mapName).then(function successCallback(response){
       var data = response.data;
       //call another function if data is empty
       if(!data.length)  
         return anotherFunction(); //make sure another function should return promise
       return data;
    });
}

【讨论】:

  • 感谢您的帖子。如果我需要打 3 个电话怎么办?我的意思是如果第一个为空,则为第二个,如果 seci=ond 为空,则为第三个。我认为这不是一个好习惯
  • 当我想在服务响应之前处理中间步骤时,这就是我的处理方式。使用和扩展承诺链是处理这种情况的好方法。我不这么认为这是不好的做法(如果您发现任何提及其状态的参考资料是不好的做法,请告诉我),谢谢;)
【解决方案2】:

首先我要说的是http请求实际上是异步执行的,以免在返回结果时停止应用程序。

所以你有两个选择,使用角度模式来调整你的方法以处理结果,所以你必须向服务传递一个回调函数,以便服务,而不是控制器进行关联。它会是这样的:

服务:

 (function () {
        "use strict";

        angular.module("manageItems").factory("manageItemsService", ["$http", "config", manageItemsService]);

        function manageItemsService($http, config) {
            var service = {
                getNewItems: getNewItems,
            };
            return service;

            function getNewItems(session, mapName, callback, errorCallback) {
                $http.get(serviceUrl + 'getNewItems/' + session + "/" + mapName).then(callback, errorCallback);;
            }

        }
    })();

控制器:

function getNewItems() {
    manageItemsService.getNewItems(mapguideService.mapName, mapguideService.sessionId, function (result) {
        //this callback will be called asynchronously when the response is available
        self.currentItems = result.data;
    }, function(error) {
        // called asynchronously if an error occurs
        // or server returns response with an error status.
    })
}

第二个选项是完全不推荐,在预期结果时插入一个循环......(坏)

希望对我有所帮助!

【解决方案3】:

代码需要做的是chain承诺。

要使getNewItems 函数可链接,返回派生的承诺:

function getNewItems() {
    //vvvv RETURN promise
    return manageItemsService.getNewItems(mapguideService.mapName, mapguideService.sessionId)
      .then(function (response) {
        self.currentItems = response.data;
        //RETURN value to chain
        return response.data;
    });
};

然后使用返回的承诺更多的操作:

getNewItems().then( function(currentItems) {
   //Evaluate current Items
   if ( ok ) {
       return "DONE";
   } else {
       //RETURN to chain something else
       return getOtherItems();
   };
}).then( function(otherItems) {
   if (otherItems == "DONE") return;
   //ELSE
   self.otherItems = otherItems;
   //Do further chaining
});

因为调用 Promise 的 .then 方法会返回一个新的派生 Promise,所以很容易创建一个 Promise 链。

可以创建任意长度的链,并且因为一个promise可以用另一个promise解决(这将进一步推迟它的解析),可以暂停/推迟promise的解析链中的任何点。这使得实现强大的 API 成为可能。

— AngularJS $q Service API Reference - Chaining Promises

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-11
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    • 2013-05-25
    • 2020-10-21
    • 2019-04-19
    相关资源
    最近更新 更多