同时发送两个ajax数据有时候混乱?

发布于 2022-09-03 23:38:48 字数 2887 浏览 8 评论 0

代码如下:

/*ajax异步获取方法*/
   function get(url,options,callback,elem){
        var xhr=new XMLHttpRequest();
        /*请求参数序列化*/
        function serialize(data){
            if(!data) return '';
            var pairs=[];
            for (var name in data){
                if(!data.hasOwnProperty(name)) continue;
                if(typeof data[name]==='function') continue;
                var value=data[name].toString();
                name=encodeURIComponent(name);
                value=encodeURIComponent(value);
                pairs.push(name+'='+value);
            }
            return pairs.join('&');
        }
        xhr.onreadystatechange=function(){
            if (xhr.readyState==4){
                if((xhr.status>=200 && xhr.status<300) || xhr.status==304){
                    callback(xhr.responseText,elem);
                }else{
                    alert("request failed:"+xhr.status);
                }
            }    
        }
        xhr.open("get",url+"?"+serialize(options),true);
        xhr.send(null);
    }
   
    /*获取服务器数据后的回调函数,将数据放进模板,并插进文档中*/

    function insert(data,element){   
        var data = JSON.parse(data);
        console.log(data.list[0]);
        var _templ =templ.innerHTML.replace(/^\s*/,'').replace(/\s*$/,'');
        
        var out_templ=[];
        for (var i=0; i<data.list.length;i++){
            var _html_templ=_templ.replace(/{{smallPhotoUrl}}/g,data.list[i].bigPhotoUrl)
                                 .replace(/{{name}}/g,data.list[i].name)
                                 .replace(/{{provider}}/g,data.list[i].provider)
                                 .replace(/{{learnerCount}}/g,data.list[i].learnerCount)
                                 .replace(/{{categoryName}}/g,data.list[i].categoryName)
                                 .replace(/{{description}}/g,data.list[i].description)
                                 .replace(/{{price}}/g,data.list[i].price);
            out_templ.push(_html_templ);
        }
        element.innerHTML=out_templ.join('');
    }
    
    function setCourse(num,callback,element){
            get('http://study.163.com/webDev/couresByCategory.htm',{pageNo:1,psize:20,type:num},callback,element);
        }       
    
    
    setCourse(10,insert,course_design);
    setCourse(20,insert,course_language);
    

为什么有时候setCourse(10,insert,course_design)(请求1)获取的没问题,但是有时候setCourse(20,insert,course_language)(请求2)显示的是前一个的内容?

  • 我在控制台里看了一下,数据的获取是没问题的,数据都被获取到了,问题应该是数据处理的环节出问题了。

  • 发现有时候是请求1的数据先获取到,请求2的数据后获取到,这时请求1的数据处理后显示没问题,但是请求2的数据处理后发现是20个请求1的数据的显示;

  • 有时候是请求2的数据先被获取到,请求2的数据后获取到,这时两个请求数据处理后的显示都是没有问题的。

  • 然后我打断点看了一下,发现好像两个请求不会先一个处理完再处理一个,应该因为ajax是异步的,好像是两个请求都发送完毕后,再一起处理的,不知道对不对。然后有时候后面的数据处理就有时候会出问题了。其实这个真正的原因是什么?这里有什么坑?怎么解决这类问题啊?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只为一人 2022-09-10 23:38:48

听你的描述,你的问题应该是race-condition,根本原因在于:

  1. javascript是门单线程语言(我们暂且不谈worker),所以对于很多耗时且不确定的操作都会放入异步序列,例如:ajaxsetTimeoutsetInterval...

  2. 并行发送多个异步操作(这里是ajax),虽然发送操作是顺序执行的,但返回结果因为时间不确定,你其实是不能期待他们的callback也是顺序执行的(取决于谁先返回)

最简单的处理方式就是在第一请求的callback里再发送第二个请求,确保他们顺序执行,如下:

setCourse(10, function(data, element) {
    insert(data, element);
    setCourse(20, insert, course_language);
}, course_design);
歌入人心 2022-09-10 23:38:48

说白了没有理解同步和异步的区别,两个ajax同时执行必然存在一个先后顺序,建议写成一个队列,简单来说,将其中一个请求写在另一个的回调函数里面。

万人眼中万个我 2022-09-10 23:38:48

既然获取没问题,肯定是你显示的处理有问题了。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文