UNPKG

latte_lib

Version:
1,711 lines (1,572 loc) 127 kB
(function() { var LATTE_NAMESPACE = "latte"; var global = (function() { return this; })(); if (!LATTE_NAMESPACE && typeof requirejs !== "undefined") return; var _define = function(module, deps, payload) { if (typeof module !== 'string') { if (_define.original) _define.original.apply(window, arguments); else { console.error('dropping module because define wasn\'t a string.'); console.trace(); } return; } if (arguments.length == 2) payload = deps; if (!_define.modules) { _define.modules = {}; _define.payloads = {}; } _define.payloads[module] = payload; _define.modules[module] = null; }; var _require = function(parentId, module, callback) { if (Object.prototype.toString.call(module) === "[object Array]") { var params = []; for (var i = 0, l = module.length; i < l; ++i) { var dep = lookup(parentId, module[i]); if (!dep && _require.original) return _require.original.apply(window, arguments); params.push(dep); } if (callback) { callback.apply(null, params); } } else if (typeof module === 'string') { var payload = lookup(parentId, module); if (!payload && _require.original) return _require.original.apply(window, arguments); if (callback) { callback(); } return payload; } else { if (_require.original) return _require.original.apply(window, arguments); } }; var resolve = function(parentId, moduleName) { if(moduleName.charAt(0) == ".") { var ps = parentId.split("/"); var base = ps.pop(); //var paths = ps.join("/"); var ms = moduleName.split("/"); var n ; while((n = ms.shift())) { if(n == "..") { ps.pop(); }else if(n != "."){ ps.push(n); } } return ps.join("/"); } return moduleName; } var normalizeModule = function(parentId, moduleName) { // normalize plugin requires if (moduleName.indexOf("!") !== -1) { var chunks = moduleName.split("!"); return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]); } // normalize relative requires /*if (moduleName.charAt(0) == ".") { var base = parentId.split("/").slice(0, -1).join("/"); moduleName = base + "/" + moduleName; while(moduleName.indexOf(".") !== -1 && previous != moduleName) { var previous = moduleName; moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, ""); } }*/ //console.log(parentId, moduleName); name = resolve(parentId, moduleName); //console.log(parentId, moduleName, name); return name; }; var lookup = function(parentId, moduleName) { moduleName = normalizeModule(parentId, moduleName); var module = _define.modules[moduleName]; if (!module) { module = _define.payloads[moduleName]; if (typeof module === 'function') { var exports = {}; var mod = { id: moduleName, uri: '', exports: exports, packaged: true }; var req = function(module, callback) { return _require(moduleName, module, callback); }; var returnValue = module(req, exports, mod, global); exports = returnValue || mod.exports; _define.modules[moduleName] = exports; delete _define.payloads[moduleName]; } module = exports || module; if(!module && moduleName.indexOf(".js") == -1) { module = _define.modules[moduleName] = lookup(parentId, moduleName + ".js"); } if(!module && moduleName.indexOf("/index") == -1) { module = _define.modules[moduleName] = lookup(parentId, moduleName+"/index"); } if(!module && moduleName.indexOf("/index.js") == -1) { module = _define.modules[moduleName] = lookup(parentId, moduleName+"/index.js"); } } if(!module) { //console.log("unload error",parentId, moduleName); } _define.modules[moduleName] = module; return module; }; function exportWindow(ns) { var require = function(module, callback) { return _require("", module, callback); }; var root = global; if (ns) { if (!global[ns]) global[ns] = {}; root = global[ns]; } if (!root.define || !root.define.packaged) { _define.original = root.define; root.define = _define; root.define.packaged = true; } if (!root.require || !root.require.packaged) { _require.original = root.require; root.require = require; root.require.packaged = true; root.require.find = function(path, all) { var pathStrNum = path.length; var callbackArray = []; Object.keys(_define.modules).forEach(function(p) { if(p.indexOf(path) == 0) { var nPath = p.substring(pathStrNum); if(all) { callbackArray.push(nPath); }else{ if(nPath.indexOf("/") == -1) { callbackArray.push(nPath); } } } }); return callbackArray; } } } exportWindow(LATTE_NAMESPACE); //window._require = require; })(); latte.global = this; this.define = latte.define; latte.config = {}; (function() { this.config = {}; }).call(latte); (function(define) {'use strict' define("latte_lib/basic/array.js", ["require", "exports", "module", "window"], function(require, exports, module, window) { var latte_lib = require("./lib.js") , events = require("./events.js") , LatteObject = require("./object"); /* 相关的splice 等返回事件 请返回latteObject 而不是Object对象 现在还没全修改完 2016-7-7 */ var LatteArray = function(data) { var self = this; this.data = []; var doEvent = function(name, value, oldValue) { var index = self.data.indexOf(this); if(index != -1) { self.emit(index + "." + name, value, oldValue, data); self.emit("change", index + "." + name, value, oldValue, data); }else{ removeEvent(this); } }; var addEvent = function(value) { value.on("change", doEvent); }; var removeEvent = function(value) { if(LatteObject.isLatteObject(value)) { value.off("change", doEvent); } }; (function init() { data.forEach(function(o, i) { var n = LatteObject.create(o); if(n) { addEvent(n); self.data[i] = n; }else{ self.data[i] = o; } }); })(); /** var data = latte_lib.object.create({ list: [] }); data.on("list", function(value, list) { }); data.set("list", [1,2,3]); */ var set = function(key, value, mode) { if(!latte_lib.isArray(key)) { key = key.toString().split("."); } if(key.length == 1) { var k = key[0]; var ov = self.data[k]; var od = data[k]; var nv; switch(mode) { case 1: break; default: removeEvent(ov); var nv = LatteObject.create(value); if(nv) { addEvent(nv); }else{ nv = value; } self.data[k] = nv; data[k] = value; return { ov: ov, nv: nv }; break; } }else{ var k = key.pop(); var o = self; var parent; for(var i = 0, len = key.length ; i < len; i++) { parent = o; o = o.get(key[i]); if(!o) { o = new LatteObject({}); parent.set(key[i], o); } } return self.get(key).set(k, value, mode); } }; this._set = set; this.set = function(key, value, mode) { var result = set(key, value , mode); if(key.indexOf(".") == -1) { self.emit("change", key, result.nv, result.ov); self.emit(key, result.nv, result.ov); } self.emit("set", key, result.nv, result.ov); return result; } this.get = function(key) { if(key == "this" && !self.data[key]) { return self; } if(!latte_lib.isArray(key)) { key = key.toString().split("."); } var v = self; if(key.length == 1) { return self.data[key[0]]; }else{ var k = key.shift(); return self.data[k].get(key); } } /** @method push @param o {any} */ this.push = function(o) { var key = self.data.length; var data = set(key, o); self.emit("splice", key, [], [data.nv]); self.emit("change", key, data.nv); } this.pop = function() { var data = set(self.length - 1, null); self.data.pop(); self.emit("splice", self.length, [data.ov], []); } /** var data = latte_lib.object.create({ a: [{ c:1 }], b:[1] }); data.get("a").on("splice", function(index, removeArray, addArray) { }); data.get("a").shift(); data.get("b").on("splice", function(index, removeArray, addArray) { }); data.get("b").shift(); */ this.shift = function() { var old = self.data.shift(); removeEvent(old); self.emit("splice", 0, [old],[]); for(var i = 0, len = self.data.length; i < len; i++) { self.emit("change", i, self.data[i]); } self.emit("change", self.data.length, null); } this.unshift = function() { var args = Array.prototype.map.call(arguments, function(value) { var o = LatteObject.create(value); if(o) { o.on("change", doEvent); } return o || value; }); self.data.unshift.apply(self.data, args); self.emit("splice", 0, [], args); for(var i = 0, len = self.data.length; i < len; i++) { self.emit("change", i, self.data[i]); } } this.splice = function(startIndex, num) { var oLength = self.data.length; var adds = Array.prototype.splice.call(arguments, 2).map(function(o) { var n = LatteObject.create(o); if(n) { n.on("change", doEvent); } return n || o; }); var olds = []; for(var i = 0; i < num; i++) { var old = self.get(startIndex+i); if(old){ removeEvent(old); olds.push(old); } } self.data.splice.apply(self.data, [startIndex, num].concat(adds)); self.emit("splice", startIndex, olds, adds); for(var i = 0, len = Math.max(oLength, self.data.length); i < len; i++) { self.emit("change", i, self.data[i]); } } this.toJSON = function() { return data; } this.indexOf = function(data) { return self.data.indexOf(data); } this.forEach = function(callback) { self.data.forEach(callback); }; this.map = function(callback) { return self.data.map(callback); } this.filter = function(callback) { return self.data.filter(callback); } Object.defineProperty(self, "length", { get: function() { return self.data.length; }, set: function(value) { throw new Error("暂时没处理") } }); this.getKeys = function() { return Object.keys(self.data); } }; latte_lib.inherits(LatteArray, events); (function() { }).call(LatteArray); module.exports = LatteArray; }); })(typeof define === "function"? define: function(name, reqs, factory) { factory(require, exports, module); }); (function(define) {'use strict' define("latte_lib/basic/async.js", ["require", "exports", "module", "window"], function(require, exports, module, window) { var latte_lib = require("./lib.js"); if(!latte_lib) { console.log("no load lib"); } /** * @class async * @namespace latte_lib * @module basic */ (function() { var _self = this; this.setImmediate = latte_lib.setImmediate; /** * 单次执行 * @method only_once * @static * @param {function} fn 只执行一次的函数 * @public * @async * @since 0.0.1 * @example var async = require("latte_lib").async; var f = async.only_once(function(data) { log(data); }); f("a"); f("b"); //"a" //error callback was already called. */ var only_once = this.only_once = function(fn) { var called = false; return function() { if (called) throw new Error("Callback was already called."); called = true; fn.apply(_self, arguments); } }; /** * 并行执行 * @method forEach * @static * @param arr {array} 需要被执行函数的数组 * @param iterator {function} 执行函数 * @param callback {function} 回调函数 * @async * @since 0.0.1 * @example var async = require("latte_lib").async; var result = []; async.forEach([1,2,3,4], function(data, callback) { if(data == 3) { callback("is 3"); }else{ result.push(data * 2); callback(); } }, function(err, data) { log(err); //is 3 log(result);// [2,4] }); var result2 = []; async.forEach([1,2,3,4], function(data, callback) { if(data == 3) { setTimeout(function() { callback("is 3"); }, 1); }else{ result2.push(data * 2); callback(); } }, function(err, data) { log(err); //is 3 log(result2);// [2,4,8] }); * */ this.forEach = this.each = function(arr, iterator, callback) { callback = callback || function(){}; if(!arr.length) { return callback(); } var completed = 0; latte_lib.forEach(arr, function (x) { iterator(x, only_once(done) ); }); function done(err) { if (err) { callback(err); callback = function () {}; } else { completed += 1; if (completed >= arr.length) { callback(); } } } }; /** 串行执行 @method forEachSeries @static @param arr {array} 需要被执行函数的数组 @param iterator {function} 执行函数 @param callback {function} 回调函数 @sync @since 0.0.1 @example var async = require("latte_lib").async; var result = []; async.forEachSeries([1,2,3,4], function(data, callback) { if(data == 3) { callback("is 3"); }else{ result.push(data * 2); callback(); } }, function(err, data) { log(err); //is 3 log(result);// [2,4] }); var result2 = []; async.forEachSeries([1,2,3,4], function(data, callback) { if(data == 3) { setTimeout(function() { callback("is 3"); }, 1); }else{ result2.push(data * 2); callback(); } }, function(err, data) { log(err); //is 3 log(result2);// [2,4,8] }); */ this.forEachSeries = this.eachSeries = function(arr, iterator, callback) { callback = callback || function() {}; if (!arr.length) { return callback(); } var completed = 0; (function iterate() { iterator(arr[completed], function (err) { if (err) { callback(err); callback = function () {}; } else { completed += 1; if (completed >= arr.length) { callback(); } else { iterate(); } } }); })(); }; this.forEachLimit = this.eachLimit = function(arr, limit, iterator, callback) { var fn = _eachLimit(limit); fn.apply(null, [arr, iterator, callback]); }; var _eachLimit = function(limit) { return function(arr, iterator, callback) { callback = callback || function() {}; if (!arr.length || limit <= 0) { return callback(); } var completed = 0; var started = 0; var running = 0; (function replenish () { if (completed >= arr.length) { return callback(); } while (running < limit && started < arr.length) { started += 1; running += 1; iterator(arr[started - 1], function (err) { if (err) { callback(err); callback = function () {}; } else { completed += 1; running -= 1; if (completed >= arr.length) { callback(); } else { replenish(); } } }); } })(); }; }; var doParallel = function (fn) { return function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [_self.each].concat(args)); }; }; var doParallelLimit = function(limit, fn) { return function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [_eachLimit(limit)].concat(args)); }; }; var doSeries = function (fn) { return function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [_self.eachSeries].concat(args)); }; }; var _asyncMap = function(eachfn, arr, iterator, callback) { arr = latte_lib.map(arr, function(x, i) { return { index: i, value: x }; }); if (!callback) { eachfn(arr, function (x, callback) { iterator(x.value, function (err) { callback(err); }); }); } else { var results = []; eachfn(arr, function (x, callback) { iterator(x.value, function (err, v) { results[x.index] = v; callback(err); }); }, function (err) { callback(err, results); }); } }; this.map = doParallel(_asyncMap); this.mapSeries = doSeries(_asyncMap); var _mapLimit = function(limit) { return doParallelLimit(limit, _asyncMap); }; this.mapLimit = function(arr, limit, iterator, callback) { return _mapLimit(limit)(arr, iterator, callback); }; this.inject = this.foldl = this.reduce = function(arr, memo, iterator, callback) { _self.eachSeries(arr, function(x, callback) { iterator(memo, x, function (err, v) { memo = v; callback(err); }); }, function (err) { callback(err, memo); }); }; this.foldr = this.reduceRight = function (arr, memo, iterator, callback) { var reversed = latte_lib.map(arr, function (x) { return x; }).reverse(); _self.reduce(reversed, memo, iterator, callback); }; var _filter = function (eachfn, arr, iterator, callback) { var results = []; arr = latte_lib.map(arr, function (x, i) { return {index: i, value: x}; }); eachfn(arr, function (x, callback) { iterator(x.value, function (v) { if (v) { results.push(x); } callback(); }); }, function (err) { callback(latte_lib.map(results.sort(function (a, b) { return a.index - b.index; }), function (x) { return x.value; })); }); }; this.select = this.filter = doParallel(_filter); this.selectSeries = this.filterSeries = doSeries(_filter); var _reject = function (eachfn, arr, iterator, callback) { var results = []; arr = latte_lib.map(arr, function (x, i) { return {index: i, value: x}; }); eachfn(arr, function (x, callback) { iterator(x.value, function (v) { if (!v) { results.push(x); } callback(); }); }, function (err) { callback(latte_lib.map(results.sort(function (a, b) { return a.index - b.index; }), function (x) { return x.value; })); }); }; this.reject = doParallel(_reject); this.rejectSeries = doSeries(_reject); var _detect = function (eachfn, arr, iterator, main_callback) { eachfn(arr, function (x, callback) { iterator(x, function (result) { if (result) { main_callback(x); main_callback = function () {}; } else { callback(); } }); }, function (err) { main_callback(); }); }; this.detect = doParallel(_detect); this.detectSeries = doSeries(_detect); this.any = this.some = function(arr, iterator, main_callback) { _self.each(arr, function (x, callback) { iterator(x, function (v) { if (v) { main_callback(true); main_callback = function () {}; } callback(); }); }, function (err) { main_callback(false); }); }; this.all = this.every = function (arr, iterator, main_callback) { _self.each(arr, function (x, callback) { iterator(x, function (v) { if (!v) { main_callback(false); main_callback = function () {}; } callback(); }); }, function (err) { main_callback(true); }); }; this.sortBy = function (arr, iterator, callback) { _self.map(arr, function (x, callback) { iterator(x, function (err, criteria) { if (err) { callback(err); } else { callback(null, {value: x, criteria: criteria}); } }); }, function (err, results) { if (err) { return callback(err); } else { var fn = function (left, right) { var a = left.criteria, b = right.criteria; return a < b ? -1 : a > b ? 1 : 0; }; callback(null, latte_lib.map(results.sort(fn), function (x) { return x.value; })); } }); }; /** 自动 并行 如果有依赖的话等依赖好了在执行 @method auto @static @param {json} tasks @param {function} callback @async @since 0.0.1 @example var async = require("latte_lib").async; async.auto({ a: ["c",function(callback) { log("a"); callback(null,3); }], b: function(callback) { log("b"); callback(null, 1); }, c: function(callback) { log("c"); callback(null, 2); }, d: ["a", function(callback) { log("d"); callback(null, 4); }] }, function(err, results) { log("err:",err); log("results:", results);// {"b":1,"c":2,"a":3,"d":4} }); async.auto({ a: ["c",function(callback) { log("a"); callback("is 3", 3); }], b: function(callback) { log("b"); callback(null, 1); }, c: function(callback) { log("c"); callback(null, 2); }, d: ["a", function(callback) { log("d"); callback(null, 4); }] }, function(err, results) { log("err:",err); // is 3 log("results:", results);// {"b":1,"c":2, "a":3} }); */ this.auto = function (tasks, callback) { callback = callback || function () {}; var keys = latte_lib.keys(tasks); var remainingTasks = keys.length if (!remainingTasks) { return callback(); } var results = {}; var listeners = []; var addListener = function (fn) { listeners.unshift(fn); }; var removeListener = function (fn) { for (var i = 0; i < listeners.length; i += 1) { if (listeners[i] === fn) { listeners.splice(i, 1); return; } } }; var taskComplete = function () { remainingTasks-- latte_lib.forEach(listeners.slice(0), function (fn) { fn(); }); }; addListener(function () { if (!remainingTasks) { var theCallback = callback; // prevent final callback from calling itself if it errors callback = function () {}; theCallback(null, results); } }); latte_lib.forEach(keys, function (k) { var task = latte_lib.isArray(tasks[k]) ? tasks[k]: [tasks[k]]; var taskCallback = function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } if (err) { var safeResults = {}; latte_lib.forEach(latte_lib.keys(results), function(rkey) { safeResults[rkey] = results[rkey]; }); safeResults[k] = args; callback(err, safeResults); // stop subsequent errors hitting callback multiple times callback = function () {}; } else { results[k] = args; latte_lib.setImmediate(taskComplete); } }; var requires = task.slice(0, Math.abs(task.length - 1)) || []; var ready = function () { return latte_lib.reduce(requires, function (a, x) { return (a && results.hasOwnProperty(x)); }, true) && !results.hasOwnProperty(k); }; if (ready()) { task[task.length - 1](taskCallback, results); } else { var listener = function () { if (ready()) { removeListener(listener); task[task.length - 1](taskCallback, results); } }; addListener(listener); } }); }; this.retry = function(times, task, callback) { var DEFAULT_TIMES = 5; var attempts = []; // Use defaults if times not passed if (typeof times === 'function') { callback = task; task = times; times = DEFAULT_TIMES; } // Make sure times is a number times = parseInt(times, 10) || DEFAULT_TIMES; var wrappedTask = function(wrappedCallback, wrappedResults) { var retryAttempt = function(task, finalAttempt) { return function(seriesCallback) { task(function(err, result){ seriesCallback(!err || finalAttempt, {err: err, result: result}); }, wrappedResults); }; }; while (times) { attempts.push(retryAttempt(task, !(times-=1))); } _self.series(attempts, function(done, data){ data = data[data.length - 1]; (wrappedCallback || callback)(data.err, data.result); }); } // If a callback is passed, run this as a controll flow return callback ? wrappedTask() : wrappedTask }; this.waterfall = function (tasks, callback) { callback = callback || function () {}; if (!latte_lib.isArray(tasks)) { var err = new Error('First argument to waterfall must be an array of functions'); return callback(err); } if (!tasks.length) { return callback(); } var wrapIterator = function (iterator) { return function (err) { if (err) { callback.apply(null, arguments); callback = function () {}; } else { var args = Array.prototype.slice.call(arguments, 1); var next = iterator.next(); if (next) { args.push(wrapIterator(next)); } else { args.push(callback); } latte_lib.setImmediate(function () { iterator.apply(null, args); }); } }; }; wrapIterator(_self.iterator(tasks))(); }; var _parallel = function(eachfn, tasks, callback) { callback = callback || function () {}; if (latte_lib.isArray(tasks)) { eachfn.map(tasks, function (fn, callback) { if (fn) { fn(function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } callback.call(null, err, args); }); } }, callback); } else { var results = {}; eachfn.each(latte_lib.keys(tasks), function (k, callback) { tasks[k](function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } results[k] = args; callback(err); }); }, function (err) { callback(err, results); }); } }; /** 并行 @method parallel @async @param {function[]} tasks @param {function} callback @example var async = require("latte_lib").async; async.parallel([ function(cb) { cb(null, 1); }, function(cb) { setTimeout(function() { cb("is 2"); }, 1); }, function(cb) { cb(null, 3); } ],function(err, result) { log(err); //is 2 log(result);//[1,null,3] }); */ this.parallel = function (tasks, callback) { _parallel({ map: _self.map, each: _self.each }, tasks, callback); }; this.parallelLimit = function(tasks, limit, callback) { _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback); }; /** @method series @async @param {function[]} tasks @param {function} callback @example var async = require("latte_lib").async; async.series([ function(cb) { cb(null, 1); }, function(cb) { setTimeout(function() { cb("is 2"); }, 1); }, function(cb) { cb(null, 3); } ],function(err, result) { log(err); //is 2 log(result);//[1,null] }); */ this.series = function (tasks, callback) { callback = callback || function () {}; if (latte_lib.isArray(tasks)) { _self.mapSeries(tasks, function (fn, callback) { if (fn) { fn(function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } callback.call(null, err, args); }); } }, callback); } else { var results = {}; _self.eachSeries(_keys(tasks), function (k, callback) { tasks[k](function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } results[k] = args; callback(err); }); }, function (err) { callback(err, results); }); } }; this.iterator = function (tasks) { var makeCallback = function (index) { var fn = function () { if (tasks.length) { tasks[index].apply(null, arguments); } return fn.next(); }; fn.next = function () { return (index < tasks.length - 1) ? makeCallback(index + 1): null; }; return fn; }; return makeCallback(0); }; this.apply = function (fn) { var args = Array.prototype.slice.call(arguments, 1); return function () { return fn.apply( null, args.concat(Array.prototype.slice.call(arguments)) ); }; }; var _concat = function (eachfn, arr, fn, callback) { var r = []; eachfn(arr, function (x, cb) { fn(x, function (err, y) { r = r.concat(y || []); cb(err); }); }, function (err) { callback(err, r); }); }; this.concat = doParallel(_concat); this.concatSeries = doSeries(_concat); this.whilst = function (test, iterator, callback) { if (test()) { iterator(function (err) { if (err) { return callback(err); } _self.whilst(test, iterator, callback); }); } else { callback(); } }; this.doWhilst = function (iterator, test, callback) { iterator(function (err) { if (err) { return callback(err); } var args = Array.prototype.slice.call(arguments, 1); if (test.apply(null, args)) { _self.doWhilst(iterator, test, callback); } else { callback(); } }); }; this.until = function(test, iterator, callback) { if (!test()) { iterator(function (err) { if (err) { return callback(err); } _self.until(test, iterator, callback); }); } else { callback(); } }; this.doUntil = function (iterator, test, callback) { iterator(function (err) { if (err) { return callback(err); } var args = Array.prototype.slice.call(arguments, 1); if (!test.apply(null, args)) { _self.doUntil(iterator, test, callback); } else { callback(); } }); }; this.queue = function (worker, concurrency) { if (concurrency === undefined) { concurrency = 1; } function _insert(q, data, pos, callback) { if (!q.started){ q.started = true; } if (!_isArray(data)) { data = [data]; } if(data.length == 0) { // call drain immediately if there are no tasks return latte_lib.setImmediate(function() { if (q.drain) { q.drain(); } }); } latte_lib.forEach(data, function(task) { var item = { data: task, callback: typeof callback === 'function' ? callback : null }; if (pos) { q.tasks.unshift(item); } else { q.tasks.push(item); } if (q.saturated && q.tasks.length === q.concurrency) { q.saturated(); } latte_lib.setImmediate(q.process); }); } var workers = 0; var q = { tasks: [], concurrency: concurrency, saturated: null, empty: null, drain: null, started: false, paused: false, push: function (data, callback) { _insert(q, data, false, callback); }, kill: function () { q.drain = null; q.tasks = []; }, unshift: function (data, callback) { _insert(q, data, true, callback); }, process: function () { if (!q.paused && workers < q.concurrency && q.tasks.length) { var task = q.tasks.shift(); if (q.empty && q.tasks.length === 0) { q.empty(); } workers += 1; var next = function () { workers -= 1; if (task.callback) { task.callback.apply(task, arguments); } if (q.drain && q.tasks.length + workers === 0) { q.drain(); } q.process(); }; var cb = only_once(next); worker(task.data, cb); } }, length: function () { return q.tasks.length; }, running: function () { return workers; }, idle: function() { return q.tasks.length + workers === 0; }, pause: function () { if (q.paused === true) { return; } q.paused = true; q.process(); }, resume: function () { if (q.paused === false) { return; } q.paused = false; q.process(); } }; return q; }; this.priorityQueue = function(worker, concurrency) { function _compareTasks(a, b){ return a.priority - b.priority; }; function _binarySearch(sequence, item, compare) { var beg = -1, end = sequence.length - 1; while (beg < end) { var mid = beg + ((end - beg + 1) >>> 1); if (compare(item, sequence[mid]) >= 0) { beg = mid; } else { end = mid - 1; } } return beg; } function _insert(q, data, priority, callback) { if (!q.started){ q.started = true; } if (!_isArray(data)) { data = [data]; } if(data.length == 0) { // call drain immediately if there are no tasks return latte_lib.setImmediate(function() { if (q.drain) { q.drain(); } }); } latte_lib.forEach(data, function(task) { var item = { data: task, priority: priority, callback: typeof callback === 'function' ? callback : null }; q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item); if (q.saturated && q.tasks.length === q.concurrency) { q.saturated(); } latte_lib.setImmediate(q.process); }); } // Start with a normal queue var q = _self.queue(worker, concurrency); // Override push to accept second parameter representing priority q.push = function (data, priority, callback) { _insert(q, data, priority, callback); }; // Remove unshift function delete q.unshift; return q; }; this.cargo = function (worker, payload) { var working = false, tasks = []; var cargo = { tasks: tasks, payload: payload, saturated: null, empty: null, drain: null, drained: true, push: function (data, callback) { if (!latte_lib.isArray(data)) { data = [data]; } latte_lib.forEach(data, function(task) { tasks.push({ data: task, callback: typeof callback === 'function' ? callback : null }); cargo.drained = false; if (cargo.saturated && tasks.length === payload) { cargo.saturated(); } }); latte_lib.setImmediate(cargo.process); }, process: function process() { if (working) return; if (tasks.length === 0) { if(cargo.drain && !cargo.drained) cargo.drain(); cargo.drained = true; return; } var ts = typeof payload === 'number' ? tasks.splice(0, payload) : tasks.splice(0, tasks.length); var ds = latte_lib.map(ts, function (task) { return task.data; }); if(cargo.empty) cargo.empty(); working = true; worker(ds, function () { working = false; var args = arguments; latte_lib.forEach(ts, function (data) { if (data.callback) { data.callback.apply(null, args); } }); process(); }); }, length: function () { return tasks.length; }, running: function () { return working; } }; return cargo; }; var _console_fn = function (name) { return function (fn) { var args = Array.prototype.slice.call(arguments, 1); fn.apply(null, args.concat([function (err) { var args = Array.prototype.slice.call(arguments, 1); if (typeof console !== 'undefined') { if (err) { if (console.error) { console.error(err); } } else if (console[name]) { latte_lib.forEach(args, function (x) { console[name](x); }); } } }])); }; }; this.log = _console_fn('log'); this.dir = _console_fn('dir'); this.memoize = function (fn, hasher) { var memo = {}; var queues = {}; hasher = hasher || function (x) { return x; }; var memoized = function () { var args = Array.prototype.slice.call(arguments); var callback = args.pop(); var key = hasher.apply(null, args); if (key in memo) { latte_lib.nextTick(function () { callback.apply(null, memo[key]); }); } else if (key in queues) { queues[key].push(callback); } else { queues[key] = [callback]; fn.apply(null, args.concat([function () { memo[key] = arguments; var q = queues[key]; delete queues[key]; for (var i = 0, l = q.length; i < l; i++) { q[i].apply(null, arguments); } }])); } }; memoized.memo = memo; memoized.unmemoized = fn; return memoized; }; this.unmemoize = function (fn) { return function () { return (fn.unmemoized || fn).apply(null, arguments); }; }; this.times = function (count, iterator, callback) { var counter = []; for (var i = 0; i < count; i++) { counter.push(i); } return _self.map(counter, iterator, callback); }; this.timesSeries = function (count, iterator, callback) { var counter = []; for (var i = 0; i < count; i++) { counter.push(i); } return _self.mapSeries(counter, iterator, callback); }; /** @method seq @static @async @param {function[]} functions @return {function} @since 0.0.1 @example var async = require("latte_lib").async; var fun = async.seq(function(a, callback) { log("1",a);//2 callback(null, a+1, a-1); }, function(data1, data2, callback) { log("2",data1,data2);//3,1 callback("is 2", (data1 + data2 + 2) / (data1- data2 + 2) ); }); fun(2, function(err,b,c) { log(err ,b,c);//is 2, 1.5 }); */ this.seq = function (/* functions... */) { var fns = arguments; return function () { var that = this; var args = Array.prototype.slice.call(arguments); var callback = args.pop(); _self.reduce(fns, args, function (newargs, fn, cb) { fn.apply(that, newargs.concat([function () { var err = arguments[0]; var nextargs = Array.prototype.slice.call(arguments, 1); cb(err, nextargs); }])) }, function (err, results) { callback.apply(that, [err].concat(results)); }); }; }; this.compose = function (/* functions... */) { //颠倒参数 return _self.seq.apply(null, Array.prototype.reverse.call(arguments)); }; var _applyEach = function (eachfn, fns /*args...*/) { var go = function () { var that = this; var args = Array.prototype.slice.call(arguments); var callback = args.pop(); return eachfn(fns, function (fn, cb) { fn.apply(that, args.concat([cb])); }, callback); }; if (arguments.length > 2) { var args = Array.prototype.slice.call(arguments, 2); return go.apply(this, args); } else { return go; } }; this.applyEach = doParallel(_applyEach); this.applyEachSeries = doSeries(_applyEach); /** 循环执行出现错误停止 @method forever @static @param fn {function} 循环执行到函数 @param callback {function} 循环执行出现错误之后回调函数 @example var async = require("latte_lib").async; var i = 0; async.forever(function(next) { if(++i == 3) { next("is 3"); }else{ log("forever", i); next(); }; }, function(err) { log(err); }); */ this.forever = function (fn, callback) { function next(err) { if (err) { if (callback) { return callback(err); } throw err; } fn(next); } next(); }; }).call(module.exports); }); })(typeof define === "function"? define: function(name, reqs, factory) { factory(require, exports, module); }); (function(define) {'use strict' define("latte_lib/basic/events.js", ["require", "exports", "module", "window"], function(require, exports, module, window) { var events; var latte_lib = require("./lib.j