Wscats/articles

关于Angular服务Request异步请求的详细分析

Wscats opened this issue · 1 comments

首先这里我简单写个例子来方便您的理解

var request = {
    post: function() {
        var errorCallback = {
            error: function(f) {
                this.fun = f;
            },
            fun: function(data) {}
        };
        successCallback = {
            success: function(f) {
                return this.fun = f, console.log(this.fun), errorCallback;
            },
            fun: function(data) {
                console.log(data)
            }
        };
        returnData = {
            wsscat: "hello"
        };
        //成功
        //var a = successCallback.fun(returnData);
        a = successCallback.fun;
        setTimeout('a(returnData)', 1000)
        return successCallback;
        }
        }
        request.post().success(function(data) {
            console.log("123");
            console.log(data);
        })
        console.log("wscat's test");

这里首先要理解一点很重要的就是异步回调,Javascript的异步回调其实就两个常用方法,
setTimeout定时这类和ajax请求这类
上面代码跟angular的request服务类似,首先是这个request对象,就相当于angular注入request服务之后返回的request对象
这个对象写了一个post方法,而post方法里面这有两个回调对象分别是
errorCallback和successCallback
还有一个模拟ajax请求返回的returnData对象

returnData = {
            wsscat: "hello"
        };

这个在angular里面则是ajax请求服务器返回给你的json对象
我们看看这段代码执行之后会log出什么的信息,如下图
image
如果熟悉Javascript的话这里不难理解,首先是输出的函数信息是因为success()函数里面的console.log(this.fun)这句
request.post().success()
success()里面首先this.fun = f这句是,把匿名的回调函数赋给successCallback对象里面的fun方法,保存起来让后面setTimeout进行回调
所以我们可以看到首先执行出来的是打印出来的回调函数,然后就是代码最后一句的
console.log("wscat's test");
明白了上述这个流程之后就可以很好的理解angular封装的request服务这一块
只不过angular里面的回调不是setTimeout回调,而是换成了$http回调而已

$http.get(url).success(function(data, status, headers, config) {
//code
})

而$http请求又因为根据返回的成功或者失败把数据
用相应的方法带到我们放到了被匿名回调函数覆盖,对象successCallback的fun里面
而带数据到fun里面就是下面这两句
successCallback.fun(returnData);
errorCallback.fun(returnData);
后面我再深入说一下

$http.get(url).success(function(data, status, headers, config) {
//code
})
  • data:这个不用再多叙述了,我们上面做了这么多其实就是想拿服务器返回给我们的data
  • status:http响应状态码,这个是很基础的东西,但我还是简单说说
  • 200:不用怀疑就是请求成功的意思
  • 304:就是你请求已经被允许的情况下,服务器发现你需要的东西还是跟之前一样没变,则返回给你304
  • 404:请求失败了,请求的资源再服务器没有发现
  • 500:看到5一般就是服务器出错了
  • 常看到的就这几个吧
  • header:头信息
  • config:生成原始请求的设置对象,如下图
    image

再往下看,其实post请求和get请求区别是不大的
只是这里get更简单明了,你直接传url过来就行了,相比post请求接口还要带上各种需要请求的参数
但再仔细了解的话,其实post跟get在这里其实都走get请求
image

Request服务源码

.service('Request', [
    '$http',
    '$cookies',
    '$rootScope',
    '$window',
    '$cookieStore',
    '$location',
    function($http, $cookies, $rootScope, $window, $cookieStore, $location) {
        var request = {
            post: function(api, map, successCallback) {
                $rootScope.dataLoadCount++;
                $rootScope.isLoading = $rootScope.dataLoadCount != 0;
                var url = '../test.php?api=' + encodeURIComponent(api);
                //console.log('[http requestURL]:' + api);
                //~ alert(api);
                var json = '{}';
                if (angular.isDefined(map)) {
                    json = angular.toJson(map);
                }

                //console.log('[http requestJson]:' + json);
                url += '&data=' + encodeURIComponent(json);
                var errorCallback = {
                    error: function(f) {
                        this.fun = f;
                    },
                    fun: function(data) {}
                };
                var successCallback = {
                    success: function(f) {
                        return this.fun = f, errorCallback;
                    },
                    fun: function(data) {}
                };
                $http.get(url).success(function(data, status, headers, config) {
                    console.log(config);
                    // this callback will be called asynchronously
                    // when the response is available
                    $rootScope.dataLoadCount--;
                    $rootScope.isLoading = $rootScope.dataLoadCount != 0;

                    //console.log('[http success responseData]:' + angular.toJson(data));
                    //~ alert('[http success responseData]:'+angular.toJson(data));
                    var returnData = {
                        code: data.state.code,
                        msg: data.state.msg,
                        data: data.data
                    };
                    if (returnData.code == 1) {
                        successCallback.fun(returnData);
                    } else {
                        if (returnData.code == 99) {
                            alert(returnData.msg);
                            $cookieStore.remove('token');
                            $cookieStore.remove('userid');
                            delete $cookies.token;
                            delete $cookies.userid;
                            $rootScope.isLogined = false;
                            $rootScope.$broadcast('refreshFooter');
                            switch ($rootScope.isWeiXinLogin()) {
                                case true:
                                    $location.path('login');
                                    break;
                                case false:
                                    $location.path('loginWebapp');
                                    break;
                            }

                            return;
                        }
                        errorCallback.fun(returnData);
                    }
                }).
                error(function(data, status, headers, config) {
                    // called asynchronously if an error occurs
                    // or server returns response with an error status.
                    $rootScope.dataLoadCount--;
                    $rootScope.isLoading = $rootScope.dataLoadCount != 0;

                    //console.log('[http error responseData]:' + angular.toJson(data));
                    //~ alert('[http error responseData]:status:'+status);
                    var returnData = {
                        code: 0,
                        msg: '网络请求失败',
                        data: {}
                    };
                    errorCallback.fun(returnData);
                });

                return successCallback;
            },
            get: function(url, successCallback) {
                $rootScope.dataLoadCount++;
                $rootScope.isLoading = $rootScope.dataLoadCount != 0;
                var errorCallback = {
                    error: function(f) {
                        this.fun = f;
                    },
                    fun: function(data) {}
                };
                var successCallback = {
                    success: function(f) {
                        return this.fun = f, errorCallback;
                    },
                    fun: function(data) {}
                };
                $http({
                    method: 'GET',
                    url: url
                }).success(function(data, status, headers, config) {
                    // this callback will be called asynchronously
                    // when the response is available
                    $rootScope.dataLoadCount--;
                    $rootScope.isLoading = $rootScope.dataLoadCount != 0;

                    //console.log('[http success responseData]:' + data);
                    var returnData = {
                        code: 1,
                        msg: '请求成功',
                        data: data
                    };
                    successCallback.fun(data);
                }).
                error(function(data, status, headers, config) {
                    // called asynchronously if an error occurs
                    // or server returns response with an error status.
                    $rootScope.dataLoadCount--;
                    $rootScope.isLoading = $rootScope.dataLoadCount != 0;
                    //console.log('[http error responseData]:' + angular.toJson(data));
                    var returnData = {
                        code: 0,
                        msg: '网络请求失败',
                        data: ""
                    };
                    errorCallback.fun(returnData);
                });
                return successCallback;
            }
        }
        return request;
    }
])