SlideShare a Scribd company logo
Jscex
案例、经验、阻碍、展望
    赵劼 - 2012.6
关于我
• 赵劼 / 老赵 / Jeffrey Zhao / 赵姐夫
• 日写代码三百行,不辞长作程序员
• 博客:http://blog.zhaojie.me/
• 微博:@老赵
• F#, JavaScript, Scala, C#, Python, .NET, Mono...
• 痛恨Java语言
内容提纲

• 简介
• 案例
• 经验
• 阻碍
• 展望
简介
关注人数

• Node.js流程控制模块(80多个)
 •   Async:2500+
 •   Step:900+
 •   Jscex:600+
 •   Fiber:500+
 •   …
唐凤大侠好评
HTML 5
实验室
电子工业出版社
回归JavaScript的
异步流程控制
Jscex是什么?

• JavaScript Computation EXpression
• JavaScript语言扩展,用于改善某些常
  见场景下的编程(如异步编程)

• F#计算表达式特性的JavaScript移植
 •   受“计算表达式”特性启发
 •   为JavaScript设计,基于JavaScript实现
Jscex不是什么?

• 另⼀一种语言:
 •   Jscex是百分百的JavaScript

• 框架
 •   Jscex是类库,能够与几乎任何类库/框架⼀一起使用

• JavaScript引擎/运行时
 •   在任何ECMAScript 3上执行
浅尝辄止
冒泡排序
var compare = function (x, y) {
    return x - y;
}

var swap = function (a, i, j) {
    var t = a[x]; a[x] = a[y]; a[y] = t;
}

var bubbleSort = function (array) {
    for (var x = 0; x < array.length; x++) {
        for (var y = 0; y < array.length - x; y++) {
            if (compare(array[y], array[y + 1]) > 0) {
                swap(array, y, y + 1);
            }
        }
    }
}
做成动画
var compare = function (x, y, callback) {         var innerLoop = function (array, x, y, callback) {
    setTimeout(10, function () {                      if (y < array.length - x) {
        callback(x - y);                                  compare(array[y], array[y + 1], function (r) {
    });                                                        if (r > 0) {
}                                                                  swap(array, y, y + 1, function () {
                                                                        innerLoop(array, x, y + 1, callback);
var swap = function (a, i, j, callback) {                          });
    var t = a[x]; a[x] = a[y]; a[y] = t;                       } else {
    repaint(a);                                                    innerLoop(array, x, y + 1, callback);
                                                               }
    setTimeout(20, callback);                             });
}                                                     } else {
                                                          callback();
var outerLoop = function (array, x, callback) {       }
    if (x < array) {                              }
        innerLoop(array, x, 0, function () {
             outerLoop(array, x + 1, callback);   outerLoop(array, 0, function () {
        });                                           console.log("done!");
    } else {                                      });
        callback();
    }
}
做成动画
                                                                               !
var compare = function (x, y, callback) {         var innerLoop = function (array, x, y, callback) {
    setTimeout(10, function () {                      if (y < array.length - x) {



                                                                             啊
        callback(x - y);                                  compare(array[y], array[y + 1], function (r) {




                                                           么
    });                                                        if (r > 0) {
}                                                                  swap(array, y, y + 1, function () {




                                                         什
                                                                        innerLoop(array, x, y + 1, callback);
var swap = function (a, i, j, callback) {                          });




                             是
    var t = a[x]; a[x] = a[y]; a[y] = t;                       } else {




                            D
    repaint(a);                                                    innerLoop(array, x, y + 1, callback);
                                                               }




                           M
    setTimeout(20, callback);                             });
}                                                     } else {



                         T
                                                          callback();
var outerLoop = function (array, x, callback) {       }



               这
    if (x < array) {                              }
        innerLoop(array, x, 0, function () {
             outerLoop(array, x + 1, callback);   outerLoop(array, 0, function () {
        });                                           console.log("done!");
    } else {                                      });
        callback();
    }
}
冒泡排序动画
var compareAsync = eval(Jscex.compile("async", function (x, y) {
     $await(Jscex.Async.sleep(10)); // each "compare" takes 10 ms.
     return x - y;
}));

var swapAsync = eval(Jscex.compile("async", function (a, x, y) {
     var t = a[x]; a[x] = a[y]; a[y] = t; // swap
     repaint(a); // repaint after each swap
     $await(Jscex.Async.sleep(20)); // each "swap" takes 20 ms.
}));

var bubbleSortAsync = eval(Jscex.compile("async", function (array) {
     for (var x = 0; x < array.length; x++) {
         for (var y = 0; y < array.length - x; y++) {
             var r = $await(compareAsync(array[y], array[y + 1]));
             if (r > 0) $await(swapAsync(array, y, y + 1));
         }
     }
}));
冒泡排序动画
var compareAsync = eval(Jscex.compile("async", function (x, y) {
     $await(Jscex.Async.sleep(10)); // each "compare" takes 10 ms.
     return x - y;
}));

var swapAsync = eval(Jscex.compile("async", function (a, x, y) {
     var t = a[x]; a[x] = a[y]; a[y] = t; // swap
     repaint(a); // repaint after each swap
     $await(Jscex.Async.sleep(20)); // each "swap" takes 20 ms.
}));

var bubbleSortAsync = eval(Jscex.compile("async", function (array) {
     for (var x = 0; x < array.length; x++) {
         for (var y = 0; y < array.length - x; y++) {
             var r = $await(compareAsync(array[y], array[y + 1]));
             if (r > 0) $await(swapAsync(array, y, y + 1));
         }
     }
}));
异步编程十分困难
破坏代码局部性

• 程序员习惯线性地表达算法
• 异步代码将逻辑拆分地支离破碎
• 难以
•   异步操作之间的协作及组合
•   处理异常及取消
异步函数
// 使用异步构造器执行编译后的代码
var somethingAsync = eval(Jscex.compile("async",
    function (...) {
        // 实现
    }
));
响应
function () {
    var res = $await(<async work>);
}
响应
function () {
    var res = $await(<async work>);
}

        HTTP请求
          UI事件
        时钟回调
        查询响应
      Web Service响应
        代理消息
function () {
          var img = $await(readAsync("http://..."));
          console.log("loaded!");
          $await(writeAsync("./files/..."));
          console.log("saved!");
      }

                            =
(function () {
    var _b_ = Jscex.builders["async"];
    return _b_.Start(this,
        _b_.Delay(function () {
            _b_.Bind(readAsync(...), function (img) {
                console.log("loaded!");
                return _b_.Bind(writeAsync(...), function () {
                    console.log("saved!");
                    return _b_.Normal();
                });
            });
        })
    );
})
I/O并行

• 许多程序是I/O密集型应用
 •   使用Web服务
 •   使用磁盘上的数据

• 网络和磁盘速度发展很慢
• I/O资源天然可以并行
 •   提高性能的关键方式
首要设计原则
Jscex即JavaScript

• 语言特性
• 语言语义
• 编程体验
语言特性
• 支持几乎所有JavaScript语言功能
 •   循环:while / for / for...in / do
 •   判断:if / switch
 •   错误处理:try...catch...finally
 •   其他:return / break / continue / throw

• 嵌套函数
• 不支持的语言特性
 •   with块
 •   带标签的break和continue
 •   switch内带条件的break
语言语义

• 保持完整的JavaScript语义
• 独立的“bind”操作(例如$await)
 •   语言里的唯⼀一扩展
 •   表现形式为“方法调用”
 •   清楚表明“特殊”的操作
编程体验

• 如JavaScript⼀一般编写、执行、调试
• 修改后立即生效
• 没有额外的编译步骤
 •   代码执行过程中由JIT编译器生成代码
案例
有JS的地方就有Jscex

• 浏览器
• Node.js
• PhoneGap
• Windows 8 Metro
• ……
工作台
Jscex:案例、经验、阻碍、展望
Jscex:案例、经验、阻碍、展望
Jscex:案例、经验、阻碍、展望
Jscex:案例、经验、阻碍、展望
“工作台”简介

• 为敏捷团队和个人打造的任务协同和事
 物管理的生产力工具

• 前后端均使用JavaScript
 •   Node.js,Socket.io,Mongoose,……

• 挑战:完全异步编程在某些同步需求下
 变得非常难于实现
Show Me the Code
exports.getUserActivity = function (uid, me_uid, count, page, cb) {
    var query = models.Activity.find(...).where(...).desc(...);
    query.exec(function (err, activities) {
        if (err) return cb(err);

           for (var i = 0; i < activities.length; i++) {
               var activity = activities[i];
               var board_id = activity.data.board.board_id;

               db.ActivityData.getBoard(board_id, function (err, board) {
                   // how to execute async operations in a loop?
               });
           }
     });
};
Jscex化
exports.getUserActivityAsync = eval(..., function (...) {
    var query = models.Activity.find(...).where(...).desc(...);
    var activities = $await(query.execAsync());

       for (var i = 0; i < activities.length; i++) {
           var activity = activities[i];
           var board_id = activity.data.board.board_id;

           var board = $await(db.ActivityData.getBoardAsync(board_id));
           ...
       }
}));
并行化
exports.getUserActivityAsync = eval(..., function (...) {
    var query = models.Activity.find(...).where(...).desc(...);
    var activities = $await(query.execAsync());

       var boardsTasks = _.map(activities, function (a) {
           var board_id = a.data.board.board_id;
           // no $await!
           return db.ActivityData.getBoardAsync(board_id);
       });

       // execute in parallel
       var boards = $await(Task.whenAll(boardsTasks));
}));
剂量率监测报警系统
Jscex:案例、经验、阻碍、展望
Jscex:案例、经验、阻碍、展望
检测声光报警系统
• 使用移动终端监测 RS131 剂量率检测设
 备,方便用户随时查看设备检测值

• 使用Cordova制作的iPhone软件(企业内
 部署)

• 场景
 •   闪光灯会循环⼀一明⼀一暗,并循环播放报警声音
 •   弹出⼀一个警告对话框提醒用户当前报警值,用户点
     击后即停止
var isAlerting = false;

function startAlert() {
    isAlerting = true; //全局报警开
    setTimeout(flashOn, 500);
}

function stopAlert() { isAlerting = false; }

function flashOn() {
    if (isAlerting) {
        window.plugins.torch.turnOn(); //开启闪光灯
        setTimeout(flashOff, 500);
    }
}

function flashOff() {
    window.plugins.torch.turnOff(); //关闭闪光灯
    if (isAlerting) { setTimeout(flashOn, 500); }
}
“闪光灯的⼀一明⼀一暗应该是⼀一个整体效
果,但我们这里不得不把它拆成2个函
数,还必须在每个函数里嵌入判断全局
开关的逻辑。”

“这种思路是非常反人类的。”

                 - 开发者
var showAlert = eval(..., function () {
    // 取消功能
    var ct = new CancellationToken();
    showFlash(ct).start(); // 启动showFlash任务,但不等待

       // 等待用户点击确认按钮
       $await(Async.onEvent(btnOK, "click"));
       ct.cancel(); // 取消showFlash任务
}));

var showFlash = eval(..., function (ct) {
    try {
        while (true) {
            window.plugins.torch.turnOn();
            $await(Async.sleep(500, ct)); // 等待500毫秒

               window.plugins.torch.turnOff();
               $await(Async.sleep(500, ct)); // 等待500毫秒
           }
       } catch (cex) {
           window.plugins.torch.turnOff();
       }
}));
Oracle旧系统改造
系统改造

• 旧方案
 •   使用⼀一个几乎透明的中间件连通客户端和Oracle
 •   几乎所有业务和计算都使用Oracle存储过程实现

• 新方案
 •   使用Node.js承担业务逻辑和计算职责
 •   使用redis作为缓存
挑战与应对

• 挑战
 •   将Oracle编写的业务逻辑移植到Node.js代码
 •   在异步环境中编写复杂业务逻辑

• 应对
 •   将Oracle存储过程自动转化为JS代码
 •   稍作修改,配合Jscex即可使用
用户评价
  更多Jscex使用经验:http://blog.sina.com.cn/u/1867000922
阻碍
思维的怪诞
人类学会了行走
冰天雪地
雪橇?

      趴着走是趋势,要迎合
NO.


      趴着走是文化,要遵循
……
异步编程

• 异步是⼀一种性质,不是⼀一种编程模型
• 异步有多种编程模型,不同场景适合不
 同模型

• 迎合语言限制并无不可,但因此开始享
 受是可悲的
固有的错误思维
• eval is (always) evil
• API太丑,eval为什么不封装?
• 看不懂,不用
• 编译很重很慢,不适合前端
• 生成的代码看不懂,难以调试
• ……
经验
用户是需要教育的

• 用户并不知道自己想要什么
• 先进的理念会遇到很大阻碍
• 从容易接受的群众下手,威逼利诱,不
 择手段
开源软件推广
• 做⼀一个开源软件很容易,推广⼀一个开源
 软件很难

• 技术外的东西十分重要,会耗费大量精
 力(文档,网站,社区,…)

• ⼀一定要争取共同开发者
• 坚持,坚持,再坚持
接受无奈

• 授权
• 公司文化
• 屌丝身份
•   高帅富:Sea.js
展望
专业化

• 更多的单元测试
•   目前测试覆盖率低于30%
•   下⼀一版本尽可能做到80%

• 更好的调试及错误定位支持
•   Source Map
•   调试工具
现代化

• 基于更成熟的解析器(Esprima)
• ECMAScript 5支持
• 更丰富的基础类库
• 更多第三方组件的支持
社区化

• 更多的社区参与度
• 吸引贡献者
•   代码
•   示例
•   文档
国际化

• 英文资源(网站,文档,…)
• 英文媒体
• 英文社区
•   Node.js
•   HTML 5
•   Windows 8
立即使用

• 基于BSD协议发布
• 站点
 •   主站:http://jscex.info/
 •   源码:https://github.com/JeffreyZhao/jscex
Q &A
谢谢

More Related Content

PDF
Jscex:案例、阻碍、体会、展望
PDF
Wind.js无障碍调试与排错
PDF
The Evolution of Async Programming (GZ TechParty C#)
PDF
JavaScript现代化排错实践
PDF
论 Python 与设计模式。
PPT
页游开发中的 Python 组件与模式
PDF
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
PDF
Python learn guide
Jscex:案例、阻碍、体会、展望
Wind.js无障碍调试与排错
The Evolution of Async Programming (GZ TechParty C#)
JavaScript现代化排错实践
论 Python 与设计模式。
页游开发中的 Python 组件与模式
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
Python learn guide

What's hot (19)

PDF
深入淺出 Web 容器 - Tomcat 原始碼分析
PDF
Python 于 webgame 的应用
PDF
Java8 lambda
PPTX
异步编程与浏览器执行模型
PDF
Ooredis
PPTX
180518 ntut js and node
PDF
Standford 2015 iOS讀書會 week2: 1. Applying MVC 2. More Swift and Foundation Fra...
PDF
Node way
PDF
PPT
JAVA内存泄漏及诊断
PDF
Use Lambdas in Android
PDF
程式人雜誌 -- 2014 年5月號
PDF
JavaScript 教程
PDF
JavaScript 快速複習 2017Q1
PDF
Arduino L2
PPT
Javascript Training
PDF
Java 開發者的函數式程式設計
PPTX
Javascript share
PDF
Node.js开发体验
深入淺出 Web 容器 - Tomcat 原始碼分析
Python 于 webgame 的应用
Java8 lambda
异步编程与浏览器执行模型
Ooredis
180518 ntut js and node
Standford 2015 iOS讀書會 week2: 1. Applying MVC 2. More Swift and Foundation Fra...
Node way
JAVA内存泄漏及诊断
Use Lambdas in Android
程式人雜誌 -- 2014 年5月號
JavaScript 教程
JavaScript 快速複習 2017Q1
Arduino L2
Javascript Training
Java 開發者的函數式程式設計
Javascript share
Node.js开发体验
Ad

Similar to Jscex:案例、经验、阻碍、展望 (7)

PPT
Underscore
PPT
Node.js在淘宝的应用实践
PDF
Maze Game
PDF
Maintainable Javascript
PDF
D2_node在淘宝的应用实践_pdf版
KEY
D2_Node在淘宝的应用实践
PDF
SeaJS 那些事儿
Underscore
Node.js在淘宝的应用实践
Maze Game
Maintainable Javascript
D2_node在淘宝的应用实践_pdf版
D2_Node在淘宝的应用实践
SeaJS 那些事儿
Ad

More from jeffz (20)

PDF
深入浅出Jscex
PDF
Mono for .NET Developers
PDF
Javascript Uncommon Programming
PDF
Jscex: Write Sexy JavaScript (中文)
PDF
Jscex: Write Sexy JavaScript
PDF
单点登录解决方案的架构与实现
PDF
Documentation Insight技术架构与开发历程
PDF
Windows Phone应用开发心得
PDF
分布式版本管理
PDF
使用.NET构建轻量级分布式框架
PDF
针对iPad平台的高性能网站架构
PDF
企业开发领域的语言特性
PDF
The Evolution of Async-Programming on .NET Platform (TUP, Full)
PDF
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
PDF
The Evolution of Async-Programming (SD 2.0, JavaScript)
PDF
大话程序员可用的算法
PDF
面向对象与生活
PDF
Windows内核技术介绍
PDF
响应式编程及框架
PDF
F#语言对异步程序设计的支持
深入浅出Jscex
Mono for .NET Developers
Javascript Uncommon Programming
Jscex: Write Sexy JavaScript (中文)
Jscex: Write Sexy JavaScript
单点登录解决方案的架构与实现
Documentation Insight技术架构与开发历程
Windows Phone应用开发心得
分布式版本管理
使用.NET构建轻量级分布式框架
针对iPad平台的高性能网站架构
企业开发领域的语言特性
The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming (SD 2.0, JavaScript)
大话程序员可用的算法
面向对象与生活
Windows内核技术介绍
响应式编程及框架
F#语言对异步程序设计的支持

Jscex:案例、经验、阻碍、展望