Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
Wscats opened this issue May 23, 2016 · 1 comment
Closed

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

Wscats opened this issue May 23, 2016 · 1 comment
Labels

Comments

@Wscats
Copy link
Owner

Wscats commented May 23, 2016

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

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

@Wscats
Copy link
Owner Author

Wscats commented May 23, 2016

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;
    }
])

@Wscats Wscats added the notes label Jun 3, 2016
@Wscats Wscats closed this as completed Aug 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant