首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

使用插件创建和扩展 jQuery 函数-6

使用插件创建和扩展 jQuery 函数-6

Timeout/Interval JavaScript 让我最为头痛的事情之一就是其与常见的线程设计的不兼容性。当我从 Swing 的 Java 用户界面转向 JavaScript Web 应用程序时,我发现我在 JavaScript 内找不到 Java 代码的多线程界面的替代物。相反,JavaScript 使用 setTimeout() 和 setInterval() 方法,这虽然有点类似于我在 Java 代码中习惯使用的线程设计,但并非完全相同。setTimeout() 方法接受一个字符串参数(充当回调方法)以及一个数字(充当超时,以毫秒为单位)。同样地,setInterval() 方法接受相同的参数,虽然此方法会不断地调用此回调方法,且以超时作为调用间的间隔。                    
将之与 Java 线程设计做对比,后者让您能创建一个线程对象,然后在相同的对象上调用 start() 和                        stop(),控制其何时运行,并在这个类定义内定义这个 run() 方法,不难看到这两个设计之间的不同。JavaScript 线程设计让您能轻松启动线程,但它有时很难停止它们。这是因为 JavaScript 线程设计依赖于 ID 来停止 超时/间隔。这些 ID 是从 setTimeout/setInterval 函数传递回来的。如下所示。                    
清单 11. JavaScript 线程
1
2
3
4
5
6
7
// creates a thread with ID of threadID,
// which will call myCallBack()
// every 1 second (1000 ms = 1 sec)
var threadID = setInterval('myCallBack', 1000);

// will stop the thread from calling myCallBack()
clearInterval(threadID);




清单 11 所示的代码其实并不实用,因为在此线程运行之前,您可能就将其关闭了。调用 setInterval(),并且在下一行上调用 clearInterval() 不起任何作用,因为 setInterval() 调用后没有暂停。解决方法如清单 12 所示。                    
清单 12. JavaScript 线程的更多内容
1
2
3
4
5
6
7
8
9
10
11
12
$(document).ready(function() {
  // store the ID as a global variable
  var threadID;

  // creates a thread with ID of threadID, which will call myCallBack()
  // every 1 second (1000 ms = 1 sec)
  threadID = setInterval('myCallBack', 1000);

  // will stop the thread from calling myCallBack()
  $("#hypotheticalStopButton").click(function(){
    clearInterval(threadID);
  });




这段代码应该会工作,因为它将 threadID 存储为一个全局变量,能在 JavaScript 代码的任何地方引用。这种解决方案对于简单的例子尚可,但是若您开始向 Web 应用程序引入更多线程并且交互变得更为困难的话,又该如何呢?具有大量全局变量的 JavaScript 代码将会更难维护,只能期待您能选中正确的线程来在不同时间停止/启动。Web 应用程序内常见的另一种情况增加了问题的复杂性,即您可能只想要函数被调用 10 次,不多也不少。这就需要再添加一个全局变量。并且,您不能在您的线程创建中创建另一个内联函数,您必须引用一个独立函数。随着页面上线程处理复杂性的增加,整体的复杂性也开始迅速增加。                    
Timers 插件的目的是通过改变您处理线程的方式来简化 Web 应用程序上的 JavaScript 线程处理,并且依我看来,让其更接近 Java 代码。与依赖于从 setInterval() 函数传递回的 threadID 不同,Timers 插件更改了设计来让您在创建之时选择线程名,这样一来,就无需存储所有的线程 ID 以便用在代码内的其他地方。好的变更还有其他一些,但是正是这些细微的更改才让处理 JavaScript 线程变得更为简单。参阅清单 13 来了解清单 12 所示的代码如何被更改以便加入 Timers 插件的。您是否也与我一样认为这看上去更容易处理呢?                    
清单 13. 具有 timers 的 JavaScript 线程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// attach an event to the start button,
// kicking off the thread
$("#start").click(function(){

// using the Timer plug-in, we attach a thread to a page element
// we call the "everyTime" function, which is analagous to the
// setInterval function.
// This function takes several arguments:
// - the timeout interval
// - the name of the thread, notice how we can choose the name here
//   and not have to worry about storing the value anywhere
// - the function to call each interval, notice how we can define
//   the inline function here, without creating an extra function
//   elsewhere, simplifying development of the thread.
// - (optional) how many times to run it before stoppping, so if
//    you put a 10 there, it would run it 10 times and then stop
// - (optional) a true/false of whether to start the next interval
//   if the previous one isn't completed yet
$("#timerSample").everyTime(500, 'growSquareThread', function(){
var t = $(this);
t.height(t.height()+5);
t.width(t.width()+5);
});
});

// attach an event to the stop button.  Notice how we can simply
// call a stop with the name of the thread, without worrying
// about the threadID
$("#stop").click(function(){
  $("#timerSample").stopTime("growSquareThread");
});




Timers 插件确实能让 JavaScript 内的线程处理更为容易。即便这些更改初看上去有些不明显,但是仔细分析后就会发现它如何使您的代码变得更整洁。根本上,您可以在一个地方定义整个线程。这意味着将要定义启动机制、延迟、要执行的循环的数量以及用来运行每个交互所需的代码。这不仅比传统 JavaScript 线程更易于处理,而且我甚至可以说这比 Java 线程都容易。有了 Timers 插件,整个线程本身都是齐备的。再也无需对处于代码内的任何地方的函数进行引用了。再也无需跟踪全局变量内的 threadID 了。再也无需复杂的代码来跟踪线程已进行的迭代的数量了。停止线程也很容易。停止线程的触发程序仍可使用线程创建时所用的线程名。甚至无需知道 threadID。
返回列表