1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
"use strict";
var callable = require("es5-ext/object/valid-callable")
, isCallable = require("es5-ext/object/is-callable")
, isValue = require("es5-ext/object/is-value")
, d = require("d")
, ee = require("event-emitter")
, isPromise = require("./is-promise");
var create = Object.create, defineProperty = Object.defineProperty, deferred, resolve, reject;
module.exports = exports = function (name, unres, onres, res) {
name = String(name);
callable(res);
if (isValue(onres)) callable(onres);
callable(unres);
defineProperty(exports._unresolved, name, d(unres));
exports._onresolve[name] = onres;
defineProperty(exports._resolved, name, d(res));
exports._names.push(name);
};
exports._names = ["done", "then", "valueOf"];
exports._unresolved = ee(
create(Function.prototype, {
then: d(function (win, fail) {
var def;
if (!this.pending) this.pending = [];
def = deferred();
this.pending.push("then", [win, fail, def.resolve, def.reject]);
return def.promise;
}),
done: d(function (win, fail) {
if (isValue(win)) callable(win);
if (isValue(fail)) callable(fail);
if (!this.pending) this.pending = [];
this.pending.push("done", arguments);
}),
resolved: d(false),
returnsPromise: d(true),
valueOf: d(function () { return this; })
})
);
exports._onresolve = {
then: function (win, fail, promiseResolve, promiseReject) {
var value, cont = this.failed ? fail : win;
if (!isValue(cont)) {
if (this.failed) promiseReject(this.value);
else promiseResolve(this.value);
return;
}
if (isCallable(cont)) {
if (isPromise(cont)) {
if (cont.resolved) {
if (cont.failed) promiseReject(cont.value);
else promiseResolve(cont.value);
return;
}
cont.done(promiseResolve, promiseReject);
return;
}
try {
value = cont(this.value);
} catch (e) {
promiseReject(e);
return;
}
promiseResolve(value);
return;
}
promiseResolve(cont);
},
done: function (win, fail) {
if (this.failed) {
if (fail) {
fail(this.value);
return;
}
throw this.value;
}
if (win) win(this.value);
}
};
exports._resolved = ee(
create(Function.prototype, {
then: d(function (win, fail) {
var value, cont = this.failed ? fail : win;
if (!isValue(cont)) return this;
if (isCallable(cont)) {
if (isPromise(cont)) return cont;
try { value = cont(this.value); }
catch (e) { return reject(e); }
return resolve(value);
}
return resolve(cont);
}),
done: d(function (win, fail) {
if (isValue(win)) callable(win);
if (isValue(fail)) callable(fail);
if (this.failed) {
if (fail) {
fail(this.value);
return;
}
throw this.value;
}
if (win) win(this.value);
}),
resolved: d(true),
returnsPromise: d(true),
valueOf: d(function () { return this.value; })
})
);
deferred = require("./deferred");
resolve = deferred.resolve;
reject = deferred.reject;
deferred.extend = exports;
|