技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> JavaScript --> Javascript的那些事儿

Javascript的那些事儿

浏览:4117次  出处信息

   目前最流行的语言是哪一种?或许是Javascript。做为一种前端语言,Javascript这几年得到了很长足的发展,AJAX或许是它发展的一个里程碑。Firefox与Chrome等现代浏览器的流行,更使得Javascript的开发效率大大提升。另一方面,Web应用的蓬勃发展,也使得Javascript编程的市场极大。

   前端技术的发展,把美工设计与逻辑实现相分离,之前把Javascript嵌入到HTML代码中的日子一去不复返了,一整个项目,都是由Javascript构成,这在之前的时代是多么不可想像的事情。不过,在众多Javascript类库的支持下,这一梦想其实早就成为现实了。程序员们也终于可以利用Javascript当一个纯粹的程序员,不掺一点美工的。

   我们或许可以从Javascript如何为数据库监控服务做为切入点聊聊这个语言。

   10g以后,EM中的等待事件图应该是最受欢迎的也被使用最多的一个功能,下面是一个例子:

   

   如何自己利用Javascript显示上面的图形呢?

   当然,我们需要有一个Javascript的图形库,把划图的工作交给它,做为DBA的我们要知道的是如何获取数据源,如何转换数据以交给图形库显示。

   图形库,我推荐用ExtJS中的相应组件。ExtJS是一个非常值得使用的Javascript类库,拥有极其丰富的例子和文档,基本上UI设计中的所有元素都可以从这些例子中找到踪迹,进而利用这些例子,实现自己业务逻辑的展现。例如,和上图EM中的等待事件图类似的例子:

   相应的源代码看起来非常简洁呢:

window.generateData = function(n, floor){
        var data = [],
            p = (Math.random() *  11) + 1,
            i;
            
        floor = (!floor && floor !== 0)? 20 : floor;
        
        for (i = 0; i < (n || 12); i++) {
            data.push({
                name: Ext.Date.monthNames[i % 12],
                data1: Math.floor(Math.max((Math.random() * 100), floor)),
                data2: Math.floor(Math.max((Math.random() * 100), floor)),
                data3: Math.floor(Math.max((Math.random() * 100), floor)),
                data4: Math.floor(Math.max((Math.random() * 100), floor)),
                data5: Math.floor(Math.max((Math.random() * 100), floor)),
                data6: Math.floor(Math.max((Math.random() * 100), floor)),
                data7: Math.floor(Math.max((Math.random() * 100), floor)),
                data8: Math.floor(Math.max((Math.random() * 100), floor)),
                data9: Math.floor(Math.max((Math.random() * 100), floor))
            });
        }
        return data;
    };
 
 window.store1 = Ext.create('Ext.data.JsonStore', {
        fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5', 'data6', 'data7', 'data9', 'data9'],
        data: generateData()
    });
 
var chart = Ext.create('Ext.chart.Chart', {
            style: 'background:#fff',
            animate: true,
            store: store1,
            legend: {
                position: 'bottom'
            },
            axes: [{
                type: 'Numeric',
                position: 'left',
                fields: ['data1', 'data2', 'data3', 'data4', 'data5', 'data6', 'data7'],
                title: 'Number of Hits',
                grid: {
                    odd: {
                        opacity: 1,
                        fill: '#ddd',
                        stroke: '#bbb',
                        'stroke-width': 1
                    }
                },
                minimum: 0,
                adjustMinimumByMajorUnit: 0
            }, {
                type: 'Category',
                position: 'bottom',
                fields: ['name'],
                title: 'Month of the Year',
                grid: true,
                label: {
                    rotate: {
                        degrees: 315
                    }
                }
            }],
            series: [{
                type: 'area',
                highlight: false,
                axis: 'left',
                xField: 'name',
                yField: ['data1', 'data2', 'data3', 'data4', 'data5', 'data6', 'data7'],
                style: {
                    opacity: 0.93
                }
            }]
        });

   store1存储的就是用来显示的数据,data是一个数组,里面有12行记录,每行对应一个月份,name即为月份的名字,其它的data1到data9代表该月份不同种类(如等待事件)的值。

   那么回到等待事件图,如何动态给图形提供数据呢?显然,每隔一个时间间隔,如5秒,我们会从数据库获取一行新的记录,把它存放进store1中,同时,删除store1中的最旧的一行记录,以此就可以实现图形的动态前移了。

   Javascript做为一门动态语言,对数据操纵的灵活性在这里得到了极大的展示,如上面逻辑对应的基本代码为:

//构造等待事件类别的名字数组
var allfields = [ 'time',
                  'total',
                  'ON CPU',
                  'User I/O' ,
                  'System I/O',
                  'Concurrency',
                  'Commit',
                  'Cluster',
                  'Scheduler',
                  'Other',                        
           ];
 
 
//初始化一行记录。
var item = {};
 
 
//给这一行记录赋值。item['time'] = xxx;
for ( var i = 1; i < allfields.length; i++) {
item[allfields[i]] = xxx;
 }
 
//删除最旧的一行记录,加入最新的一行记录
 
 store1.data.removeAt(0);
 store1.loadData([item], true);
 
//图形库看到底层的数据发生了改变,就会动态地更新UI。

   在这里,对比一下Java和Javascript这两种语言或许是很有趣的事情。想想如何使用Java去实现上面的逻辑?首先,Java中类的属性是不能动态定义的,于是你需要定义一个记录类,里面是诸如time,total,on_cpu这些属性。其次,Java中属性的名字是不能包含空格的,于是你需要为”ON CPU”定义一个类似on_cpu的变量名。还有,你不能方便地遍历一个类里面的所有属性,于是只能把上面的那个循环写成9行类似下面的语句:

   item.time=xxx;

   item.total=xxx;

   看起来Java的代码比Javascripts臃肿多了。

   写到这,再顺便一提,Javascript中类的属性可以动态定义,体现在item['time']这种写法其实等价于Java程序员非常熟悉的写法item.time。习惯了Java的语法,看到这种形式一定会感觉特别新鲜。这也许是Java和Javascript的一个最显著的区别。

   继续说说如何从Oracle数据库中得到这些等待事件类别对应的数值(active session number)。相应的查询语句如下:

select
        decode(ash.wait_class,'','ON CPU',ash.wait_class),
        decode(ash.session_state,'ON CPU','ON CPU',ash.event) ,
        round(count(1)/l_elapsed,2)  avg,
        round(max(time_waited/1000))  max_waited
    from
       gv$active_session_history ash
    where
       sample_time  >= p_pre_time - numtodsinterval(1,'SECOND') and
       sample_time  < p_cur_time - numtodsinterval(1,'SECOND')
    group by decode(ash.session_state,'ON CPU','ON CPU',ash.event),decode(ash.wait_class,'','ON CPU',ash.wait_class)

   当然,这里统计的粒度其实是等待事件,而不是等待事件类别,Javascript代码中还需要对其做进一步做汇总,才能给上面的图形提供数据,不过,这带来一个好处,有了这些等待事件的信息,我们可以在合适的时候加以展示,例如,当鼠标移到某一时刻时,显示这一时刻看对应的所有等待事件的比例图。当鼠标再次移动某个等待事件上时,只显示出这个等待事件的趋势图。

   下面就是最终的一个效果图:

   

   Javascript或许是被低估的一门语言。在WEB流行的时代,学学javascript是一个很酷的事情。

建议继续学习:

  1. 规范自己的JavaScript书写    (阅读:5964)
  2. JavaScript,只有你想不到    (阅读:5107)
  3. 我希望我知道的七个JavaScript技巧    (阅读:4544)
  4. JavaScript是Web的汇编语言(一):语义Web已死!    (阅读:4367)
  5. 能说明你的Javascript技术很烂的五个原因    (阅读:3970)
  6. javascript语句的执行过程分析    (阅读:3146)
  7. JavaScript是Web的汇编语言(二):疯狂,亦或只是精神错乱?    (阅读:2918)
  8. JS不是前端的全部    (阅读:2750)
  9. Javascript诞生记    (阅读:2690)
  10. JavaScript解析:让搜索引擎看到更真实的网页    (阅读:2593)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1