Angularjs $http wait for response

此生再无相见时 提交于 2019-12-05 15:25:30

You can't force $http.get() into synchronism. Since $http.get() is unavoidably asynchronous, you can only return a promise of a value not the value itself.

And because you need to do this when $http.get() is called, you must also return a promise under the other condition - when vCardFromLS is successfully retreived from localstorage. This ensures that the object returned to any call of $scope.getVCard() has a .then() method, ie it is a promise, regardless of whether $http.get() was called or not.

So the code should be something like this :

$scope.getVCard = function(id) {
    var vcardKey = vcardKeyPrefix + id;
    var vCardFromLS = localStorageService.get(vCardKey);
    var dfrd = $q.defer();
    if(vCardFromLS) {
        dfrd.resolve(localStorageService.get(vCardKey));
    }
    else {
        $http.get(app.common.vcardUrl(id)).success(function(data) {
            localStorageService.add(vCardKey, data);//.add() rather than .set() ?
            dfrd.resolve(data);
        }).error(function(error) {
            F1.common.error(data, function() {
                dfrd.reject('$http.get(app.common.vcardUrl(id)) failed');
            });
        });
    }
    return dfrd.promise;
};

Now you need to ensure that the response to $scope.getVCard() is handled appropriately, eg :

$scope.getVCard(id).then(function(data) {
    //success - do whatever is required with data
}, function(reason) {
    //failure - log and/or display `reason` as an error message
})

EDIT:

My "... you must also return a promise under the other condition ..." is an overstatement.

I should have said, "... you can, to make things simple, return a promise under the other condition ...".

Another possibility is to branch depending on whether a Promise or another type of object/value was returned. However, this is messy and will typically lead to some duplication of code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!