您好,欢迎访问一九零五行业门户网

JavaScript 异步编程之 jsdeferred 原理解析

1. 前言
最近在看司徒正美的《javascript框架设计》,看到异步编程的那一章介绍了jsdeferred这个库,觉得很有意思,花了几天的时间研究了一下代码,在此做一下分享。
异步编程是编写js的一个很重要的理念,特别是在处理复杂应用的时候,异步编程的技巧就至关重要。那么下面就来看看这个被称为里程碑式的异步编程库吧。
2. api源码解析
2.1 构造函数
这里使用了安全的构造函数,避免了在没有使用new调用构造函数时出错的问题,提供了两个形式俩获取deferred对象实例。
function deferred() { return (this instanceof deferred) ? this.init() : new deferred(); } // 方式1 var o1 = new deferred(); // 方式2 var o2 = deferred();
2.2 deferred.define()
这个方法可以包装一个对象,指定对象的方法,或者将deferred对象的方法直接暴露在全局作用域下,这样就可以直接使用。
deferred.methods = [parallel, wait, next, call, loop, repeat, chain]; /* @param obj 赋予该对象deferred的属性方法 @param list 指定属性方法 */ deferred.define = function(obj, list){ if(!list)list = deferred.methods; // 获取全局作用域的技巧,利用立即执行函数的作用域为全局作用域的技巧 if(!obj) obj = (function getglobal(){return this})(); // 将属性都挂载到obj上 for(var i = 0; i bar.html data }); 3. parallel([fn1, fn2, fn3]).next(function (v) { v[0] // fn1执行的结果 v[1] // fn2执行的结果 v[3] // fn3执行返回的结果 }); */ var isarray = false; // 第一种形式 if (arguments.length > 1) { dl = array.prototype.slice.call(arguments); isarray = true; // 其余两种形式,数组,类数组 } else if (array.isarray && array.isarray(dl) || typeof dl.length == number) { isarray = true; } var ret = new deferred(), // 用于归并结果的deferred对象的实例 value = {}, // 收集函数执行的结果 num = 0 ; // 计数器,当为0时说明所有任务都执行完毕 // 开始遍历,这里使用for-in其实效率不高 for (var i in dl) { // 预防遍历了所有属性,例如tostring之类的 if (dl.hasownproperty(i)) { // 利用闭包保存变量状态 (function (d, i){ // 使用deferred.next()开始一个异步任务,并且执行完成之后,收集结果 if (typeof d == function) dl[i] = d = deferred.next(d); d.next(function (v) { values[i] = v; if( --num task1返回的结果 ret[1]; // => task2返回的结果 });
为什么可以这样?我们来图解一下,加深一下理解。
我们使用了_fire中的if判断,建立了新的调用链,获得去统计计数函数(即parallel中--num)的控制权,从而使得在parallel执行异步的方法。
其它类似信息

推荐信息