Skip to content

Commit

Permalink
Passed all A+ tests
Browse files Browse the repository at this point in the history
  • Loading branch information
yanguango committed Jan 18, 2018
1 parent 01049df commit 7efda83
Show file tree
Hide file tree
Showing 14 changed files with 984 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
1 change: 1 addition & 0 deletions dist/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './src/promise';
6 changes: 6 additions & 0 deletions dist/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./src/promise"));
15 changes: 15 additions & 0 deletions dist/promise.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export declare class Promise {
private _state;
private _value;
private _handlers;
constructor(executor: (resovle: any, reject: any) => void);
private _resolve(x);
private _fulfill(result);
private _reject(error);
private _isPending();
private _isFulfilled();
private _isRejected();
private _addHandler(onFulfilled, onRejected);
private _callHandler(handler);
then(onFulfilled: any, onRejected?: any): Promise;
}
164 changes: 164 additions & 0 deletions dist/promise.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var State;
(function (State) {
State[State["Pending"] = 0] = "Pending";
State[State["Fulfilled"] = 1] = "Fulfilled";
State[State["Rejected"] = 2] = "Rejected";
})(State || (State = {}));
class Util {
static isFunction(val) {
return val && typeof val === "function";
}
static isObject(val) {
return val && typeof val === "object";
}
}
class Promise {
constructor(executor) {
this._handlers = [];
this._state = State.Pending;
executor(this._resolve.bind(this), this._reject.bind(this));
}
_resolve(x) {
if (x === this) {
throw new TypeError("Resolving object can not be the same object");
}
else if (x instanceof Promise) {
x.then(this._resolve.bind(this), this._reject.bind(this));
}
else if (Util.isObject(x) || Util.isFunction(x)) {
let called = false;
try {
const thenable = x.then;
if (Util.isFunction(thenable)) {
thenable.call(x, (result) => {
if (!called)
this._resolve(result);
called = true;
}, (error) => {
if (!called)
this._reject(error);
called = true;
});
}
else {
this._fulfill(x);
}
}
catch (ex) {
if (!called) {
this._reject(ex);
}
}
}
else {
this._fulfill(x);
}
}
_fulfill(result) {
this._state = State.Fulfilled;
this._value = result;
this._handlers.forEach(handler => this._callHandler(handler));
}
_reject(error) {
this._state = State.Rejected;
this._value = error;
this._handlers.forEach(handler => this._callHandler(handler));
}
_isPending() {
return this._state === State.Pending;
}
_isFulfilled() {
return this._state === State.Fulfilled;
}
_isRejected() {
return this._state === State.Rejected;
}
_addHandler(onFulfilled, onRejected) {
this._handlers.push({
onFulfilled,
onRejected
});
}
_callHandler(handler) {
if (this._isFulfilled() && Util.isFunction(handler.onFulfilled)) {
handler.onFulfilled(this._value);
}
else if (this._isRejected() && Util.isFunction(handler.onRejected)) {
handler.onRejected(this._value);
}
}
then(onFulfilled, onRejected) {
switch (this._state) {
case State.Pending: {
return new Promise((resolve, reject) => {
this._addHandler((value) => {
setTimeout(() => {
try {
if (Util.isFunction(onFulfilled)) {
resolve(onFulfilled(value));
}
else {
resolve(value);
}
}
catch (ex) {
reject(ex);
}
}, 0);
}, (error) => {
setTimeout(() => {
try {
if (Util.isFunction(onRejected)) {
resolve(onRejected(error));
}
else {
reject(error);
}
}
catch (ex) {
reject(ex);
}
}, 0);
});
});
}
case State.Fulfilled: {
return new Promise((resolve, reject) => {
setTimeout(() => {
try {
if (Util.isFunction(onFulfilled)) {
resolve(onFulfilled(this._value));
}
else {
resolve(this._value);
}
}
catch (ex) {
reject(ex);
}
}, 0);
});
}
case State.Rejected: {
return new Promise((resolve, reject) => {
setTimeout(() => {
try {
if (Util.isFunction(onRejected)) {
resolve(onRejected(this._value));
}
else {
reject(this._value);
}
}
catch (ex) {
reject(ex);
}
}, 0);
});
}
}
}
}
exports.Promise = Promise;
15 changes: 15 additions & 0 deletions dist/src/promise.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export declare class Promise {
private _state;
private _value;
private _handlers;
constructor(executor: (resovle: any, reject: any) => void);
private _resolve(x);
private _fulfill(result);
private _reject(error);
private _isPending();
private _isFulfilled();
private _isRejected();
private _addHandler(onFulfilled, onRejected);
private _callHandler(handler);
then(onFulfilled: any, onRejected?: any): Promise;
}
164 changes: 164 additions & 0 deletions dist/src/promise.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var State;
(function (State) {
State[State["Pending"] = 0] = "Pending";
State[State["Fulfilled"] = 1] = "Fulfilled";
State[State["Rejected"] = 2] = "Rejected";
})(State || (State = {}));
class Util {
static isFunction(val) {
return val && typeof val === "function";
}
static isObject(val) {
return val && typeof val === "object";
}
}
class Promise {
constructor(executor) {
this._handlers = [];
this._state = State.Pending;
executor(this._resolve.bind(this), this._reject.bind(this));
}
_resolve(x) {
if (x === this) {
throw new TypeError("Resolving object can not be the same object");
}
else if (x instanceof Promise) {
x.then(this._resolve.bind(this), this._reject.bind(this));
}
else if (Util.isObject(x) || Util.isFunction(x)) {
let called = false;
try {
const thenable = x.then;
if (Util.isFunction(thenable)) {
thenable.call(x, (result) => {
if (!called)
this._resolve(result);
called = true;
}, (error) => {
if (!called)
this._reject(error);
called = true;
});
}
else {
this._fulfill(x);
}
}
catch (ex) {
if (!called) {
this._reject(ex);
}
}
}
else {
this._fulfill(x);
}
}
_fulfill(result) {
this._state = State.Fulfilled;
this._value = result;
this._handlers.forEach(handler => this._callHandler(handler));
}
_reject(error) {
this._state = State.Rejected;
this._value = error;
this._handlers.forEach(handler => this._callHandler(handler));
}
_isPending() {
return this._state === State.Pending;
}
_isFulfilled() {
return this._state === State.Fulfilled;
}
_isRejected() {
return this._state === State.Rejected;
}
_addHandler(onFulfilled, onRejected) {
this._handlers.push({
onFulfilled,
onRejected
});
}
_callHandler(handler) {
if (this._isFulfilled() && Util.isFunction(handler.onFulfilled)) {
handler.onFulfilled(this._value);
}
else if (this._isRejected() && Util.isFunction(handler.onRejected)) {
handler.onRejected(this._value);
}
}
then(onFulfilled, onRejected) {
switch (this._state) {
case State.Pending: {
return new Promise((resolve, reject) => {
this._addHandler((value) => {
setTimeout(() => {
try {
if (Util.isFunction(onFulfilled)) {
resolve(onFulfilled(value));
}
else {
resolve(value);
}
}
catch (ex) {
reject(ex);
}
}, 0);
}, (error) => {
setTimeout(() => {
try {
if (Util.isFunction(onRejected)) {
resolve(onRejected(error));
}
else {
reject(error);
}
}
catch (ex) {
reject(ex);
}
}, 0);
});
});
}
case State.Fulfilled: {
return new Promise((resolve, reject) => {
setTimeout(() => {
try {
if (Util.isFunction(onFulfilled)) {
resolve(onFulfilled(this._value));
}
else {
resolve(this._value);
}
}
catch (ex) {
reject(ex);
}
}, 0);
});
}
case State.Rejected: {
return new Promise((resolve, reject) => {
setTimeout(() => {
try {
if (Util.isFunction(onRejected)) {
resolve(onRejected(this._value));
}
else {
reject(this._value);
}
}
catch (ex) {
reject(ex);
}
}, 0);
});
}
}
}
}
exports.Promise = Promise;
Empty file added dist/test/aplus_test.d.ts
Empty file.
17 changes: 17 additions & 0 deletions dist/test/aplus_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const promise_1 = require("../src/promise");
var promisesAplusTests = require("promises-aplus-tests");
const adapter = {
deferred() {
const pending = {};
pending.promise = new promise_1.Promise((resolver, reject) => {
pending.resolve = resolver;
pending.reject = reject;
});
return pending;
}
};
promisesAplusTests(adapter, function (err) {
// All done; output is in the console. Or check `err` for number of failures.
});
Loading

0 comments on commit 7efda83

Please sign in to comment.