开发者社区> 问答> 正文

求一个基于jquery或通用的js数据存储类:报错

以前用extjs的时候,其内置的数据存储功能很好很强大,现在没有用extjs,想完成一个数据存储中转功能,即外部向该数据请求读取数据,如果数据存储实体没有,那么就执行ajax请求,请求到了之后再返还给外部请求

结果还没开始写再仔细一想就卡壳了,尼玛ajax是异步的,执行ajax请求的时候数据存储实体的程序就已经return了,虽然重新写一个类实现内部变量判断和内部执行循环从而控制一直到ajax返回后才返回数据(甚至包括执行超时判断等功能)是可以的,但是想到要重写就没劲儿了

所以想问问有没有这种数据存储交互类?

展开
收起
kun坤 2020-06-07 00:35:27 687 0
1 条回答
写回答
取消 提交回答
  • 有点明白了,哈哈,异步的话,还是用回调函数吧  

    getData(function(data){
       xxx;
    });
    
    function getData(callback){
        ...;
        callback(data);
        ...;
    }



    ######ajax可以设置同步!######可以试试用 $.Deferred######

    引用来自“con”的评论

    可以试试用 $.Deferred

    谢谢,刚才看dom数发现trigger和triggerHandler函数,一查也是看到了deffered,正在试,不过没有试验成功,希望能指导下

    使用的jquery1.10.2和easyui1.4

    简单地就是一个二级联动菜单,一个事件是一级菜单联动二级菜单,另外一个事件是载入数据的时候将数据写入(不过因为二级菜单跟着一级菜单走,所以得等到二级菜单载入完毕才能写入数据)

    下面的代码都是放在$()里面的

    //设置一级菜单的二级菜单联动
    	$('#topic1').combobox({
    		onChange:function(n,o){
    			topic2Loaded=false;//因为没有搞懂deferred用法,这个是加的全局变量准备用全局变量来判断
    			var f_s;
    			//alert(1);
    			f_s=getTopic2(n);    //这个是我现在的简单的存储处理方法
    			if(f_s==false){
    				$.post('../server/t_getsubtopic.php',{father:n},function(data,sta,xhr){
    					jQuery('#topic2').combobox('clear').combobox('loadData',data.topic);
    					eval('db_topic2.'+'f'+n+'=data.topic;');
    					topic2Loaded=true;
    				},'json');
    			}else{
    				jQuery('#topic2').combobox('clear').combobox('loadData',f_s);
    				topic2Loaded=true;
    			}
    		}
    	});



           //初始化编辑器的显示内容
    	jQuery.post('../server/t_editorinit.php',function(data,sta,xhr){
    		var jjj;
    		jQuery('#topic1').combobox('clear').combobox('loadData',data.topic);
    		jQuery('#saved').attr('value',1);
    		jQuery('#subject').combobox('clear').combobox('loadData',data.subject);
    		if(data.topic.length==0){
    			jQuery.messager.alert('提示','当前无权限进行操作,请登陆后刷新本页面。','info');
    			//jQuery('#saved').window('close');
    		}else{
    			//是否读取数据,如果是的话读取数据
    			var id=getURLRequest('id');
    			if(id){
    				jQuery.post('../server/getcontent.php',{id:id},function(data,sta,xhr){
    					var topic=data.path[0];
    					//jQuery.when(jQuery('#topic1').combobox('select',topic.father.index););
    					jQuery('#topic1').combobox('select',topic.father.index);
                                            //这里就没有看懂,包括看的jquery的api里面then貌似已经废弃了的,这里执行不下去
    //					jQuery.when(jQuery('#topic1').triggerHandler(
    //						'onChange',jQuery('#topic1').combobox('getValue')
    //					)).done(jQuery('#topic2').combobox('select',topic.son.topicid));
    					jQuery('#topic2').combobox('select',topic.son.topicid);
    					//jQuery('#saved').attr('saved')=1;
    				},'json');
    			}
    		}
    	},'json');



    ######

    试了半天没有试出来,现在这样做的,但是看着好丑……

    最主要是如果超500ms没有完成载入就丑了……

    jQuery.post('../server/getcontent.php',{id:id},function(data,sta,xhr){
    		var topic=data.path[0];
            jQuery('#topic1').combobox('select',topic.father.index).delay(500).queue(function(){
                jQuery('#topic2').combobox('select',topic.son.topicid);
            });
    		jQuery('#saved').attr('saved')=1;
    	},'json');



    ######

    1、首先是通过Deferred实现的数据存储


    // 存储函数
    function getData(dfd, name) {
        var sdata = []; // 缓存所有ajax请求过的数据
        if ( sdata[name] ){
            dfd.resolve( sdata[name] );
        } else {
            $.ajax({
                url: xxx,
            }).done( function (data) {
                sdata[name] = data;
                dfd.resolve( data );
            })
        }
    }

    // 调用方式
    var dfd = $.Deferred();
    dfd.done( function (data) {
        // 拿到数据后要执行的操作
    });
    getData(dfd, "name1");



    Deferred对象的使用方式大抵如上。

    2、combobox二级菜单

    简单看了下easyui combobox的api,一级菜单被选择时,更新二级菜单内容,可以用类似下面的写法:

    $("#level_1").combobox({
        onSelect: function (record) {
            // 获取二级菜单内容并缓存,调用上面的getData
            var dfd = $.Deferred();
            dfd.done(function (data) {
                $("#level_2").combobox( 'loadData', data);
            });
            //这里的record不知道是个啥东西,可能需要加工一下再传入getData
            getData(dfd, record);
        }
    });



    不知道这种方式是不是能满足你说的菜单联动和缓存数据的需求


    ######

    引用来自“con”的评论

    1、首先是通过Deferred实现的数据存储


    // 存储函数
    function getData(dfd, name) {
        var sdata = []; // 缓存所有ajax请求过的数据
        if ( sdata[name] ){
            dfd.resolve( sdata[name] );
        } else {
            $.ajax({
                url: xxx,
            }).done( function (data) {
                sdata[name] = data;
                dfd.resolve( data );
            })
        }
    }

    // 调用方式
    var dfd = $.Deferred();
    dfd.done( function (data) {
        // 拿到数据后要执行的操作
    });
    getData(dfd, "name1");



    Deferred对象的使用方式大抵如上。

    2、combobox二级菜单

    简单看了下easyui combobox的api,一级菜单被选择时,更新二级菜单内容,可以用类似下面的写法:

    $("#level_1").combobox({
        onSelect: function (record) {
            // 获取二级菜单内容并缓存,调用上面的getData
            var dfd = $.Deferred();
            dfd.done(function (data) {
                $("#level_2").combobox( 'loadData', data);
            });
            //这里的record不知道是个啥东西,可能需要加工一下再传入getData
            getData(dfd, record);
        }
    });



    不知道这种方式是不是能满足你说的菜单联动和缓存数据的需求


    谢谢,因为没用过所以还不太清楚,不过我就当是回调函数理解的话貌似这样的确可以解决问题,有时间的时候我会试着用这个代码并学习一下deferred这个有用的东西的。

    至于之前我的解决方式整体就是这样的,不过有eval在里面真的好丑……

    var db_topic2={};//用于存储topic2的本地数据,以免频繁进行查询
    function getTopic2(father){
    	//通过查询本地dbTopic2来获取topic2的数据,如果没有的话才进行远程查询
    	//
    	father='f'+father;//转换为字符
    	var flag;
    	eval('flag=db_topic2.'+father+';');
    	if(flag){
    		return flag;
    	}else{
    		//通过数据进行查询
    		return false;
    	}
    }
    
    
    //设置一级菜单的二级菜单联动
    $('#topic1').combobox({
    	onChange:function(n,o){
    		$('#saved').prop('value','0');//设置未保存
    		var f_s;
    		f_s=getTopic2(n);
    		if(f_s==false){
    			$.post('../server/t_getsubtopic.php',{father:n},function(data,sta,xhr){
    				jQuery('#topic2').combobox('clear').combobox('loadData',data.topic);
    				eval('db_topic2.'+'f'+n+'=data.topic;');
    			},'json');
    		}else{
    			jQuery('#topic2').combobox('clear').combobox('loadData',f_s);
    		}
    	}
    });
    //载入数据时候的设置
    jQuery('#topic1').combobox('select',n.father.index).delay(500).queue(function(){
    	jQuery('#topic2').combobox('select',n.son.topicid);
    	$(this).dequeue();
    }).delay(500).queue(function(){
    	//因为存在延时,所以得在这里再延时设置已保存状态
    	$('#saved').prop('value','1');//设置已保存
    	$(this).dequeue();
    });



    看着很丑吧……

    ######
    /*
     * 获取数据方法
     * name: 数据key
     * fn: 回调函数
     */
    function getData(name, fn) {
        if(typeof getData.cache[name] != "undefined") {
            fn(getData.cache[name]);
            return;
        }
    
        $.post("index.php", { name: name }, function (data) {
            getData.cache[name] = data;
            fn(data);
        }, "json");
    }
    getData.cache = {};
    
    
    
    //使用实例
    getData("user", function (user) {
        alert(user.name);
    });



    ######

    引用来自“mr-zhuo”的评论

    /*
     * 获取数据方法
     * name: 数据key
     * fn: 回调函数
     */
    function getData(name, fn) {
        if(typeof getData.cache[name] != "undefined") {
            fn(getData.cache[name]);
            return;
        }
    
        $.post("index.php", { name: name }, function (data) {
            getData.cache[name] = data;
            fn(data);
        }, "json");
    }
    getData.cache = {};
    
    
    
    //使用实例
    getData("user", function (user) {
        alert(user.name);
    });



    谢谢,用回调函数适用范围应该更广一些。######

    这里有篇关于deferred的,不错。

    http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html

    2020-06-07 00:35:34
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
JavaScript异步编程 立即下载
Delivering Javascript to World 立即下载
编程语言如何演化-以JS的private为例 立即下载