JS闭包问题?

1.我想写一个ajaxs函数,该函数接收url数组、成功回调和失败回调为参数,将请求结果传入成功回调,注意请求结果顺序与url数组中的url一致,如ajaxs([url1,url2],success(res){},error(status){}),res是形如这样的结果,res=[res_url1,res_url2],我遇到的问题是无法将res传入success,具体看代码.

2.首先写了个ajax函数供ajaxs中调用,如下:

ajax:function(options,success,error){
        var url=options&&options.url||'',
             type=options&&options.type&&options.type.toUpperCase()||'GET',
             params=options&&formatObj(options.params)||'',
             sucFun=success||function(){},
             errFun=error||function(){},
             data=options&&options.data||{};
         if(params){
             url=url+(url.indexOf('?')==-1?'?'+params.substring(0,params.length-1):'&'+params.substring(0,params.length-1));
         }
        var xhr=new XMLHttpRequest();
        xhr.open(type,url,true);
        if(type=='POST'){
            xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
        }
        xhr.send($.isEmpty(data)?null:data);
        var res={};
        xhr.onreadystatechange=function(){
            if(xhr.readyState==4&&xhr.status==200){
                sucFun&&sucFun(JSON.parse(xhr.responseText));
                res=JSON.parse(xhr.responseText);
            }else{
                errFun&&errFun(xhr.status);
            }
        }
        function formatObj(obj){
            var str='';
            for(var i in obj){
                str+=(i+'='+obj[i])+'&';
            }
            return str;
        }
    },

然后写ajaxs函数,如下:

ajaxs:function(urls,onSuccess,onError){
        var result=[];
        var len=urls.length;
        if(len==0){
            return result;
        }
        urls.forEach(function(value,key){
            result[key]=key;
            $.ajax({
                url:value
            },function(res){
                len--;
                result[key]=res;
                if(len==0){
                    onSuccess&&onSuccess(result);
                }
            },
            function(status){
                onError(status);
                result=null;
            });
        })
    }

3.问题就是在下面这段代码:

urls.forEach(function(value,key){
            result[key]=key;
            $.ajax({
                url:value
            },function(res){
                len--;
                result[key]=res;//此时访问不到result,不知道为什么?
                if(len==0){
                    onSuccess&&onSuccess(result);
                }
            },
            function(status){
                onError(status);
                result=null;
            });
        })

4.以下是我的报错和调试信息:
报错信息

这是在执行ajax函数的成功回调时的堆栈信息,可以看到闭包ajaxs的result属性为null,但是我设置的是result={},这就导致了result[key]=res报错,求解释。
调用堆栈信息

5.为方便大家调试,直接这样调用ajaxs就可以了

ajaxs(['http://api.tianapi.com/huabian/?key=ad97b50c8552dbbacead1c7c4663058d&num=10','http://api.tianapi.com/tiyu/?key=ad97b50c8552dbbacead1c7c4663058d&num=10','http://api.tianapi.com/keji/?key=ad97b50c8552dbbacead1c7c4663058d&num=10'],function(res){console.log(res)},function(status){console.log(status)})
阅读 2k
2 个回答

就在你出问题的那段代码

function (status) {
        onError(status);
        result = null;
    }

你把result设为null了。

error的逻辑错了

当 readystate = 4 且 status 不等于 200 时才是 error

仔细琢磨其中的区别

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题