This repository has been archived on 2023-08-30. You can view files and clone it, but cannot push or open issues/pull-requests.
bytedo
/
wcui
Archived
1
0
Fork 0
wcui/js/lib/request/promise.js

224 lines
5.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
*
* @authors yutent (yutent@doui.cc)
* @date 2016-11-26 16:35:45
*
*/
'use strict';
define(function() {
var _Promise = function(callback) {
this.callback = [];
var _this = this;
if (typeof this !== 'object')
throw new TypeError('Promises must be constructed via new');
if (typeof callback !== 'function')
throw new TypeError('Argument must be a function');
callback(
function(val) {
_resolve(_this, val);
},
function(val) {
_reject(_this, val);
}
);
};
var self = {
_state: 1,
_fired: 1,
_val: 1,
callback: 1
};
_Promise.prototype = {
constructor: _Promise,
_state: 'pending',
_fired: false,
_fire: function(yes, no) {
if (this._state === 'rejected') {
if (typeof no === 'function') no(this._val);
else throw this._val;
} else {
if (typeof yes === 'function') yes(this._val);
}
},
_then: function(yes, no) {
if (this._fired) {
var _this = this;
fireCallback(_this, function() {
_this._fire(yes, no);
});
} else {
this.callback.push({ yes: yes, no: no });
}
},
then: function(yes, no) {
yes = typeof yes === 'function' ? yes : _yes;
no = typeof no === 'function' ? no : _no;
var _this = this;
var next = new _Promise(function(resolve, reject) {
_this._then(
function(val) {
try {
val = yes(val);
} catch (err) {
return reject(err);
}
},
function(val) {
try {
val = no(val);
} catch (err) {
return reject(err);
}
resolve(val);
}
);
});
for (var i in _this) {
if (!self[i]) next[i] = _this[i];
}
return next;
},
done: done,
catch: fail,
fail: fail
};
_Promise.all = function(arr) {
return _some(false, arr);
};
_Promise.race = function(arr) {
return _some(true, arr);
};
_Promise.defer = defer;
// -----------------------------------------------------------
function _yes(val) {
return val;
}
function _no(err) {
throw err;
}
function done(callback) {
return this.then(callback, _no);
}
function fail(callback) {
return this.then(_yes, callback);
}
function defer() {
var obj = {};
obj.promise = new this(function(yes, no) {
obj.resolve = yes;
obj.reject = no;
});
return obj;
}
//成功的回调
function _resolve(obj, val) {
if (obj._state !== 'pending') return;
if (val && typeof val.then === 'function') {
var method = val instanceof _Promise ? '_then' : 'then';
val[method](
function(v) {
_transmit(obj, v, true);
},
function(v) {
_transmit(obj, v, false);
}
);
} else {
_transmit(obj, val, true);
}
}
//失败的回调
function _reject(obj, val) {
if (obj._state !== 'pending') return;
_transmit(obj, val, false);
}
// 改变Promise的_fired值并保持用户传参触发所有回调
function _transmit(obj, val, isResolved) {
obj._fired = true;
obj._val = val;
obj._state = isResolved ? 'fulfilled' : 'rejected';
fireCallback(obj, function() {
for (var i in obj.callback) {
obj._fire(obj.callback[i].yes, obj.callback[i].no);
}
});
}
function fireCallback(obj, callback) {
var isAsync = false;
if (typeof obj.async === 'boolean') isAsync = obj.async;
else isAsync = obj.async = true;
if (isAsync) setTimeout(callback, 0);
else callback();
}
function _some(bool, iterable) {
iterable = Array.isArray(iterable) ? iterable : [];
var n = 0;
var res = [];
var end = false;
return new _Promise(function(yes, no) {
if (!iterable.length) no(res);
function loop(obj, idx) {
obj.then(
function(val) {
if (!end) {
res[idx] = val;
n++;
if (bool || n >= iterable.length) {
yes(bool ? val : res);
end = true;
}
}
},
function(val) {
end = true;
no(val);
}
);
}
for (var i = 0, len = iterable.length; i < len; i++) {
loop(iterable[i], i);
}
});
}
// ---------------------------------------------------------------
var nativePromise = window.Promise;
if (/native code/.test(nativePromise)) {
nativePromise.prototype.done = done;
nativePromise.prototype.fail = fail;
if (!nativePromise.defer) nativePromise.defer = defer;
}
return (window.Promise = nativePromise || _Promise);
});
wcui是一套基于`Web Components`的UI组件库, 宗旨是追求简单、实用、不花哨。
JavaScript 95.2%
CSS 4.8%