extend-promise.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /*!
  2. * extend-promise v0.0.6
  3. * Homepage https://github.com/cnwhy/extend-promise#readme
  4. * License BSD-2-Clause
  5. */
  6. (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  7. (function (name, factory) {
  8. if (typeof define === 'function' && (define.amd || define.cmd)) {
  9. define([], factory);
  10. } else if (typeof window !== "undefined" || typeof self !== "undefined") {
  11. var global = typeof window !== "undefined" ? window : self;
  12. global[name] = factory();
  13. if(typeof global.Promise == "function"){
  14. global[name].auto(global.Promise);
  15. }
  16. } else {
  17. throw new Error("加载 " + name + " 模块失败!,请检查您的环境!")
  18. }
  19. })('extendPromise',function(){
  20. var extendPromise = require("../index");
  21. extendPromise.auto = function(P){
  22. extendPromise.extendClass(P);
  23. extendPromise.extendPrototype(P);
  24. };
  25. return extendPromise;
  26. });
  27. },{"../index":2}],2:[function(require,module,exports){
  28. module.exports = {
  29. extendClass : require("./src/extendClass"),
  30. extendPrototype : require("./src/extendPrototype")
  31. };
  32. },{"./src/extendClass":3,"./src/extendPrototype":4}],3:[function(require,module,exports){
  33. 'use strict';
  34. var utils = require('./utils')
  35. var isArray = utils.isArray
  36. ,isEmpty = utils.isEmpty
  37. ,isFunction = utils.isFunction
  38. ,isPlainObject = utils.isPlainObject
  39. ,arg2arr = utils.arg2arr
  40. function extendClass(Promise,obj,funnames){
  41. var QClass,source;
  42. if(obj){
  43. source = true
  44. QClass = obj;
  45. }else{
  46. QClass = Promise;
  47. }
  48. function asbind(name){
  49. if(isArray(funnames)){
  50. var nomark = false;
  51. for(var i = 0; i<funnames.length; i++){
  52. if(funnames[i] == name){
  53. nomark = true;
  54. break;
  55. }
  56. }
  57. if(!nomark) return false;
  58. }
  59. if(source){
  60. return !isFunction(QClass[name]);
  61. }
  62. return true;
  63. }
  64. if(!QClass.Promise && Promise != obj) QClass.Promise = Promise;
  65. //defer defer为最基础的实现
  66. if(isFunction(Promise) && isFunction(Promise.prototype.then)){
  67. QClass.defer = function() {
  68. var resolve, reject;
  69. var promise = new Promise(function(_resolve, _reject) {
  70. resolve = _resolve;
  71. reject = _reject;
  72. });
  73. return {
  74. promise: promise,
  75. resolve: resolve,
  76. reject: reject
  77. };
  78. }
  79. }else if(isFunction(Promise.defer)){
  80. QClass.defer = function(){return Promise.defer();}
  81. }else if(isFunction(Promise.deferred)){
  82. QClass.defer = function(){return Promise.deferred();}
  83. }else{
  84. throw new TypeError("此类不支持扩展!")
  85. }
  86. //delay
  87. if(asbind("delay")){
  88. QClass.delay = function(ms,value){
  89. var defer = QClass.defer();
  90. setTimeout(function(){
  91. //console.log('==========')
  92. defer.resolve(value);
  93. },ms)
  94. return defer.promise;
  95. }
  96. }
  97. //resolve
  98. if(asbind("resolve")){
  99. QClass.resolve = function(obj){
  100. var defer = QClass.defer();
  101. defer.resolve(obj);
  102. return defer.promise;
  103. }
  104. }
  105. //reject
  106. if(asbind("reject")){
  107. QClass.reject = function(obj){
  108. var defer = QClass.defer();
  109. defer.reject(obj);
  110. return defer.promise;
  111. }
  112. }
  113. function getall(map,count){
  114. if(!isEmpty(count)){
  115. count = +count > 0 ? +count : 0;
  116. }
  117. return function(promises) {
  118. var defer = QClass.defer();
  119. var data,_tempI = 0;
  120. var fillData = function(i){
  121. var _p = promises[i];
  122. QClass.resolve(_p).then(function(d) {
  123. if(typeof count != 'undefined'){
  124. data.push(d);
  125. }else{
  126. data[i] = d;
  127. }
  128. if (--_tempI == 0 || (!map && count && data.length>=count)) {
  129. defer.resolve(data);
  130. }
  131. }, function(err) {
  132. if (isEmpty(count)) {
  133. defer.reject(err);
  134. }else if(--_tempI == 0){
  135. defer.resolve(data);
  136. }
  137. })
  138. _tempI++;
  139. }
  140. if(isArray(promises)){
  141. data = [];
  142. if(promises.length == 0){defer.resolve(data)};
  143. for(var i = 0; i<promises.length; i++){
  144. fillData(i);
  145. }
  146. }else if(map && isPlainObject(promises)){
  147. var _mark = 0;
  148. data = {}
  149. for(var i in promises){
  150. fillData(i);
  151. _mark++;
  152. }
  153. if(_mark == 0) defer.resolve(data)
  154. }else{
  155. defer.reject(new TypeError("参数错误"));
  156. }
  157. return defer.promise;
  158. }
  159. }
  160. //all
  161. if(asbind("all")){
  162. QClass.all = getall()
  163. }
  164. if(asbind("allMap")){
  165. QClass.allMap = getall(true);
  166. }
  167. if(asbind("some")){
  168. QClass.some = function(proArr,count){
  169. count = +count >= 0 ? +count : 0;
  170. return getall(false,count)(proArr)
  171. }
  172. }
  173. //map
  174. if(asbind("map")){
  175. QClass.map = function(data,mapfun,options){
  176. var defer = QClass.defer();
  177. var promiseArr = [];
  178. var concurrency = options ? +options.concurrency : 0
  179. //无并发控制
  180. if(concurrency == 0 || concurrency != concurrency){
  181. for(var i in data){
  182. promiseArr.push(mapfun(data[i],i,data));
  183. }
  184. QClass.all(promiseArr).then(defer.resolve,defer.reject)
  185. return defer.promise;
  186. }
  187. var k = 0;
  188. var keys = (function(){
  189. var ks = [];
  190. for(var k in data){
  191. ks.push(k);
  192. }
  193. return ks;
  194. })();
  195. function next(){
  196. if(k<keys.length){
  197. var key = keys[k];
  198. var promise = QClass.resolve(mapfun(data[key],key,data)).then(function(v){
  199. next();
  200. return v;
  201. },defer.reject);
  202. promiseArr.push(promise);
  203. concurrency--;
  204. k++;
  205. }else{
  206. QClass.all(promiseArr).then(defer.resolve,defer.reject);
  207. }
  208. }
  209. do{
  210. next()
  211. }while(concurrency>0 && k<keys.length)
  212. return defer.promise
  213. }
  214. }
  215. function race(proArr) {
  216. var defer = QClass.defer();
  217. for (var i = 0; i < proArr.length; i++) {
  218. (function() {
  219. var _i = i;
  220. var _p = proArr[_i];
  221. QClass.resolve(_p).then(function(data) {
  222. defer.resolve(data);
  223. }, function(err) {
  224. defer.reject(err);
  225. })
  226. })()
  227. }
  228. return defer.promise;
  229. }
  230. //any | race
  231. if(asbind("race")){
  232. QClass.race = race;
  233. }
  234. if(asbind("any")){
  235. QClass.any = race;
  236. }
  237. /*封装CPS*/
  238. //callback Adapter
  239. function cbAdapter(defer){
  240. return function(err,data){
  241. if(err) return defer.reject(err);
  242. defer.resolve(data)
  243. }
  244. }
  245. function nfcall(f){
  246. var _this = this === QClass ? null : this;
  247. var defer = QClass.defer();
  248. var argsArray = arg2arr(arguments,1)
  249. argsArray.push(cbAdapter(defer))
  250. f.apply(_this,argsArray)
  251. return defer.promise;
  252. }
  253. if(asbind("nfcall")){
  254. QClass.nfcall = nfcall;
  255. }
  256. if(asbind("nfapply")){
  257. QClass.nfapply = function(f,args){
  258. var _this = this === QClass ? null : this;
  259. var defer = QClass.defer();
  260. if(isArray(args)){
  261. args.push(cbAdapter(defer));
  262. f.apply(_this,args)
  263. }else{
  264. throw TypeError('"args" is not Array')
  265. }
  266. return defer.promise;
  267. }
  268. }
  269. QClass.denodeify = function(f){
  270. var _this = this === QClass ? null : this;
  271. return function(){
  272. return nfcall.apply(_this,[].concat([f],arg2arr(arguments)))
  273. }
  274. }
  275. return QClass;
  276. }
  277. module.exports = extendClass;
  278. },{"./utils":5}],4:[function(require,module,exports){
  279. function extendPrototype(Promise){
  280. var prototype = Promise.prototype;
  281. prototype.done = function(ok,no){
  282. this.then(function(value){
  283. if(typeof ok == "function") setTimeout(function(){ok(value)},0);
  284. },function(err){
  285. if(typeof no == "function") setTimeout(function(){no(err)},0)
  286. else setTimeout(function(){throw err;},0)
  287. })
  288. }
  289. prototype.spread = function(ok,no){
  290. return this.then(function(value){
  291. return ok.apply(null,value);
  292. },no);
  293. }
  294. prototype.fail =
  295. prototype['catch'] = function(no){
  296. return this.then(null,no);
  297. }
  298. /**
  299. * 捕获指定错误
  300. * @param {object} errType 错误类型/错误的值
  301. * @param {Function} fn 处理函数,拒绝值做为参数传入
  302. * @return {Promise}
  303. */
  304. prototype.catchOf = function(errType,fn){
  305. fn = fn || errType;
  306. return this.then(null,function(err){
  307. var futype = typeof fn;
  308. if(futype != "function"){throw err;}
  309. if(errType === fn){
  310. return fn(err);
  311. }
  312. if(errType === err || (typeof errType == 'function' && err instanceof errType)){
  313. return fn(err);
  314. }else{
  315. throw err;
  316. }
  317. });
  318. }
  319. prototype.error = function(no){
  320. return this.catchOf(Error,no);
  321. }
  322. /**
  323. * 不管状态,必定执行,且装态继续传递
  324. * @param {[type]} fun [description]
  325. * @return {Promise}
  326. */
  327. prototype.fin =
  328. prototype['finally'] = function(fun){
  329. var run = function(y,n){try{fun(y,n);}catch(e){}}
  330. return this.then(function(data){
  331. run(data);
  332. return data;
  333. },function(err){
  334. run(null,err);
  335. throw err;
  336. })
  337. }
  338. return Promise;
  339. }
  340. module.exports = extendPrototype;
  341. },{}],5:[function(require,module,exports){
  342. 'use strict';
  343. exports.isPlainObject = function(obj) {
  344. if (obj === null || typeof(obj) !== "object" || obj.nodeType || (obj === obj.window)) {
  345. return false;
  346. }
  347. if (obj.constructor && !Object.prototype.hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf")) {
  348. return false;
  349. }
  350. return true;
  351. }
  352. exports.isArray = function(obj){
  353. return Object.prototype.toString.call(obj) == "[object Array]"
  354. }
  355. exports.isFunction = function(obj){
  356. return typeof obj == "function"
  357. }
  358. exports.isEmpty = function(obj){
  359. return typeof obj == 'undefined' || obj === null;
  360. }
  361. exports.arg2arr = function(arg,b,s){
  362. return Array.prototype.slice.call(arg,b,s);
  363. }
  364. },{}]},{},[1])