JavaScript異步編程之Jscex無創(chuàng)痕切入jQueryUI
我們使用tab插件:
- <script>
- $(function () {
- $("#tabs").tabs({ event: "mouseover" });
- });
- </script>
效果:鼠標(biāo)劃過就可以切換tab.
目前Jscex主要包括以下幾點(diǎn)功能:
JIT編譯器:在運(yùn)行時(shí)動(dòng)態(tài)編譯代碼,主要用于開發(fā)環(huán)境。
AOT編譯器:在執(zhí)行前靜態(tài)編譯代碼。靜態(tài)編譯后的代碼可以脫離JIT編譯器執(zhí)行,因此主要用于生產(chǎn)環(huán)境。
異步編程庫(kù):基于Jscex生成的monadic代碼,大大簡(jiǎn)化JavaScript下的異步編程難度。
異步編程的重要性不言而喻,對(duì)于JavaScript來說更是如此。JavaScript并沒有提供任何能夠阻塞代碼執(zhí)行過程的機(jī)制,任何一個(gè)“耗時(shí)”的操作都必須寫成異步的模式。傳統(tǒng)的異步操作會(huì)在完成時(shí)通過回調(diào)函數(shù)傳回結(jié)果,我們可以在回調(diào)函數(shù)中進(jìn)行下面的工作。
但這也是造成異步編程十分困難的主要原因。我們一直習(xí)慣于“線性”地編寫邏輯,但是異步操作所帶來的大量回調(diào)把我們的算法分解地支離破碎。我們不能用if來實(shí)現(xiàn)邏輯分支,也不能用while/for/do來實(shí)現(xiàn)循環(huán)。更不提異步操作之間的組合、錯(cuò)誤處理以及取消操作了。
Jscex及它的異步編程庫(kù)便是為了解決這些困難而誕生的。
Jscex是JavaScript Computation EXpressions的縮寫,它為JavaScript語(yǔ)言提供了一個(gè)monadic擴(kuò)展,能夠顯著提高一些常見場(chǎng)景下的編程體驗(yàn)。Jscex項(xiàng)目完全使用JavaScript編寫,能夠在任意支持ECMAScript 3的執(zhí)行引擎里使用,包括各瀏覽器及服務(wù)器端JavaScript環(huán)境(例如 Node.js )。
目前Jscex主要包括以下幾點(diǎn)功能:
JIT編譯器:在運(yùn)行時(shí)動(dòng)態(tài)編譯代碼,主要用于開發(fā)環(huán)境。
AOT編譯器:在執(zhí)行前靜態(tài)編譯代碼。靜態(tài)編譯后的代碼可以脫離JIT編譯器執(zhí)行,因此主要用于生產(chǎn)環(huán)境。
異步編程庫(kù):基于Jscex生成的monadic代碼,大大簡(jiǎn)化JavaScript下的異步編程難度。
異步編程的重要性不言而喻,對(duì)于JavaScript來說更是如此。JavaScript并沒有提供任何能夠阻塞代碼執(zhí)行過程的機(jī)制,任何一個(gè)“耗時(shí)”的操作都必須寫成異步的模式。傳統(tǒng)的異步操作會(huì)在完成時(shí)通過回調(diào)函數(shù)傳回結(jié)果,我們可以在回調(diào)函數(shù)中進(jìn)行下面的工作。
但這也是造成異步編程十分困難的主要原因。我們一直習(xí)慣于“線性”地編寫邏輯,但是異步操作所帶來的大量回調(diào)把我們的算法分解地支離破碎。我們不能用if來實(shí)現(xiàn)邏輯分支,也不能用while/for/do來實(shí)現(xiàn)循環(huán)。更不提異步操作之間的組合、錯(cuò)誤處理以及取消操作了。
Jscex及它的異步編程庫(kù)便是為了解決這些困難而誕生的。
后來,官網(wǎng)幫這個(gè)tab插件擴(kuò)展了一個(gè)自動(dòng)切換的功能,只需要這樣寫就行:
- <script type="text/javascript">
- $(function () {
- var t = $("#tabs").tabs();
- t.tabs("rotate", 3000, false);
- });
- </script>
擴(kuò)展的代碼如下:
- $.extend($.ui.tabs.prototype, {
- rotation: null,
- rotate: function (ms, continuing) {
- var self = this,
- o = this.options;
- var rotate = self._rotate || (self._rotate = function (e) {
- clearTimeout(self.rotation);
- self.rotation = setTimeout(function () {
- var t = o.selected;
- self.select(++t < self.anchors.length ? t : 0);
- }, ms);
- if (e) {
- e.stopPropagation();
- }
- });
- var stop = self._unrotate || (self._unrotate = !continuing
- ? function (e) {
- if (e.clientX) { // in case of a true click
- self.rotate(null);
- }
- }
- : function (e) {
- t = o.selected;
- rotate();
- });
- // start rotation
- if (ms) {
- this.element.bind("tabsshow", rotate);
- this.anchors.bind(o.event + ".tabs", stop);
- rotate();
- // stop rotation
- } else {
- clearTimeout(self.rotation);
- this.element.unbind("tabsshow", rotate);
- this.anchors.unbind(o.event + ".tabs", stop);
- delete this._rotate;
- delete this._unrotate;
- }
- return this;
- }
- });
- })(jQuery);
依然是那么費(fèi)解的代碼!在官方?jīng)]有擴(kuò)展之前,我們可以用Jscex介樣子實(shí)現(xiàn):
- <script type="text/javascript">
- var swicthAsync = eval(Jscex.compile("async", function () {
- var tabCount = $("#tabs ul li").length;
- while (true) {
- for (var i = 0; i < tabCount; i++) {
- $await(Jscex.Async.sleep(2000));
- $('#tabs').tabs({ selected: i });
- }
- }
- }));
- $(function () {
- $("#tabs").tabs();
- swicthAsync().start();
- });
- </script>
可以看得出來,這樣的話Jscex沒有對(duì)JqueryUI做任何介入,Jscex只是外部控制的一層殼。這樣無法對(duì)測(cè)試出Jscex是否能與沖突或者異常,那么,我們就來用Jscex重寫官方的擴(kuò)展方法吧!
- $.extend($.ui.tabs.prototype, {
- rotation: null,
- rotate: function (ms, continuing) {
- var self = this,
- o = this.options;
- var swicthAsync = eval(Jscex.compile("async", function () {
- while (true) {
- for (var i = 0; i < self.anchors.length; i++) {
- $await(Jscex.Async.sleep(ms));
- self.select(i);
- }
- }
- }));
- swicthAsync().start();
- return this;
- }
- });
- })(jQuery);
運(yùn)行效果如下,一切正常!但是continuing參數(shù)暫時(shí)沒有起作用,該參數(shù)是決定用戶在選中后是否繼續(xù)循環(huán)下去,這個(gè)就留個(gè)大家自己去完善吧~~~~
***的Jscex 庫(kù),請(qǐng)上https://github.com/JeffreyZhao/jscex或者h(yuǎn)ttp://www.sndacode.com/projects/jscex/wiki下載吧····
原文:http://www.cnblogs.com/iamzhanglei/archive/2011/08/21/2148628.html
【系列文章】