Upgrade to Pro — share decks privately, control downloads, hide ads and more …

javascript异步编程探索.pdf

lichen
March 18, 2013
1.6k

 javascript异步编程探索.pdf

lichen

March 18, 2013
Tweet

Transcript

  1. JavaScript 异步编程探索 var KEYWORDs = { author: “李诚”, } date:

    “2013/3/18”, alias: “使用消息触发、Promise/A、二次编译提升异步编程体验” , E-mail: “[email protected]
  2. var 目录 = { } • javascript异步编程简介 • javascript异步编程优化: 

    消息触发  Promise/A  二次编译 • 分析总结
  3. var 预期 = { } • 了解JS中异步回调引发的问题 • 理解针对该问题提出的三种优化方案 •

    在实际编程过程中,在某些具体情况 下引入某种解决方案 • Open our mind
  4. var 同步和异步 = { } function synFn() { var i

    = 0; while(i < 10000) { i++; } return i; } function asynFn(i) { i = i || 0; if(i <= 10000) { setTimeout(function() { i++; asynFn(i); }, 100) } return i; }
  5. var JS异步执行的操作 = { } • Ajax(XMLHttpRequest) • setTimeout/setInterval •

    CSS3 Transition/Animation • postMessage • Web Workers • Web Sockets • and more… 所有耗时的操作都应进行分解异步执行
  6. var JS异步编程的问题 = { } 保证A、B、C、D、E方法顺序执行 同步执行时: A(); B(); C();

    D(); E(); 异步时: A(function() { B(function() { C(function() { D(function() { E(); }); }); }); });
  7. var JS异步编程的问题 = { } • 代码结构支离破碎 • 可读性降低,提高的代码的复杂度 •

    对回调的严重依赖 • 非线性的适应 流程混乱、编程体验糟糕
  8. var 消息触发 = { } var proxy = new EventProxy();

    proxy.assign( 'A', 'B', 'C', D ); A ( function() { proxy.trigger( 'A' ); }); B ( function() { proxy.trigger( 'B' ); }); C ( function() { proxy.trigger( 'C' ); });
  9. var Promise/A = { } CommonJS提出的异步编程模型规范 A promise is defined

    as an object that has a function as the value for the property ‘then‘. then(fulfilledHandler, errorHandler, progressHandler) then方法返回另一个promise对象,形成promise管道 目的: 提供统一的异步编程API规范
  10. var Promise/A = { } 一个Promise/A规范的实现提供如下的编程体验: promise.then(done, fail, progress).then(…).then(…) Promise的三种状态:

    [unfulfilled, fulfilled, failed] 实现:when.js、Dojo/Deferred.js、$.Deferred、 WinJS.Promise (win8 metro)
  11. var Promise/A参数传递 = { } • resolve(param) -> fulfilledHandler(param) •

    reject(param) -> errorHandler(param) 通过promise的resolve和reject方法来向后 传递参数
  12. var jQuery deferred = { } $.Deferred: Jquery 1.5版本基于Promise/A规范实现 应用:

    $.ajax返回对象的变更: <1.5:$.ajax方法返回XHR对象 >=1.5:$.ajax返回$.deferred对象
  13. var $.Deferred使用示例 = { } 普通青年一般都这样写Ajax请求: $.ajax({ url: "test.html", success:

    function() { alert("哈哈,成功了!"); }, error: function() { alert("出错啦!"); } });
  14. var $.Deferred使用示例 = { } 普通青年一般都这样写Ajax请求: $.ajax({ url: "test.html", success:

    function() { alert("哈哈,成功了!"); }, error: function() { alert("出错啦!"); } });
  15. var $.Deferred使用示例 = { } $.ajax("test.html") .done(function() { alert("哈哈,成功了!"); })

    .fail(function() { alert("出错啦!"); }); $.ajax(“test.html”).then( function() { alert("哈哈,成功了!"); }, function() { alert("出错啦!"); }) OR
  16. var 异步函数改造 = { } 把一个普通异步执行的函数改造成一个 deferred对象函数 function wait() {

    setTimeout(function() { alert(‘hello’); }, 2000) } function wait() { var defer = $.Deferred(); setTimeout(function() { alert(‘hello’); defer.reslove(); }, 2000) return defer.promise(); }
  17. var defer = function() { var callback; return { resolve:

    function(val) { var value = parsePms(val); callback && value.then(callback) }, promise: { then: function(fn) { var d = defer(); callback = function(val) { d.resolve(fn(val)); } return d.promise; } } } }
  18. var parsePms = function (value) { if (value && typeof

    value.then === "function") { return value; } else { return { then: function (callback) { return parsePms(callback(value)); } } } }
  19. var PROMISE/A简单实现 = { } var log = function(a) {

    var d = defer(); setTimeout(function() { console.log(a); d.resolve(++a); }, 1000) return d.promise; } log(1).then(log).then(log).then(log); Usage:
  20. var Wind.js = { } Wind.js is an advanced library

    which enable us to control flow with plain JavaScript for asynchronous programming (and more) without additional pre-compiling steps.
  21. var Wind.js小例子 = { } var printAsync = eval(Wind.compile("async", function

    (text) { $await(Wind.Async.sleep(1000)); console.log(text); })); var task = printAsync("Hello World"); tack.start(); 1s后控制台打印出信息
  22. var Wind.js = { } Wind。Js之我见: 1. 依赖eval(eval is evil让大多数人望而却步,

    即便老赵跟着别人屁股后面喊...) 2. 缺少文档 3. 二次编译调试的复杂性(有还是没有啊?)
  23. var 对比 = { } 1. 消息触发: 简单,回调的近亲,猜中开头, 也要猜中结尾 2.

    PROMISE/A: 接口统一友好,理解难了点 3. 二次编译wind.js 最靠近同步编写异步执行的style, 适应性较难,需要换换口味