diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml new file mode 100644 index 0000000..eaccf28 --- /dev/null +++ b/.idea/jsLibraryMappings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e170033 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/part-1-task-2.iml b/.idea/part-1-task-2.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/part-1-task-2.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..807bc9c --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + DEFINITION_ORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project + + + true + + + + DIRECTORY + + false + + + + + + + + + 1476024655527 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/SuperPromise.js b/lib/SuperPromise.js index bc50312..63ef56b 100644 --- a/lib/SuperPromise.js +++ b/lib/SuperPromise.js @@ -2,35 +2,158 @@ // NO REQUIRE class SuperPromise { + constructor(executor) { + this.state = 'PENDING'; + this.handlers = []; + this.value = null; + + executor(this.resolve.bind(this), this.reject.bind(this)); } - then(onResolve) { + handle (handler) { + if (this.state === 'PENDING') { + this.handlers.push(handler); + } else { + if (this.state === 'FULFILLED' && + typeof handler.onFulfilled === 'function') { + handler.onFulfilled(this.value); + } + if (this.state === 'REJECTED' && + typeof handler.onRejected === 'function') { + handler.onRejected(this.value); + } + } + } + + done (onFulfilled, onRejected) { + var self = this; + setTimeout(function () { + self.handle({ + onFulfilled: onFulfilled, + onRejected: onRejected + }); + }, 0); } - catch(onRejection) { + then (onFulfilled, onRejected) { + var self = this; + return new SuperPromise(function (resolve, reject) { + return self.done(function (result) { + if (typeof onFulfilled === 'function') { + try { + return resolve(onFulfilled(result)); + } catch (ex) { + return reject(ex); + } + } else { + return resolve(result); + } + }, function (error) { + if (typeof onRejected === 'function') { + try { + return resolve(onRejected(error)); + } catch (ex) { + return reject(ex); + } + } else { + return reject(error); + } + }); + }); + } + catch(onRejected) { + return this.then(null, onRejected); } /* PART 2 */ - static resolve() { - // Your code here... + + fulfill(result) { + this.handlers.forEach(handle); + this.handlers = null; + this.state = 'FULFILLED'; + this.value = result; + } + + getThen(value) { + var t = typeof value; + if (value && (t === 'object' || t === 'function')) { + var then = value.then; + if (typeof then === 'function') { + return then; + } + } + return null; + } + + static resolve(result) { + return new SuperPromise((resolve) => resolve(result)); } - static reject() { - // Your code here... + resolve(result) { + var self = this; + try { + var then = self.getThen(result); + if (then) { + doResolve(then.bind(result), resolve, reject); + return; + } + this.fulfill(result); + } catch (e) { + this.reject(e); + } + return this; } - static all() { - // Your code here... + // нужно создавать static отдельно, иначе tasks не видит их как функцию + static reject(error) { + return new SuperPromise((reject) => reject(error)); } - static race() { - // Your code here... + reject(error) { + this.state = 'REJECTED'; + this.value = error; } + static doResolve(fn, onFulfilled, onRejected) { + var done = false; + try { + fn(function (value) { + if (done) return; + done = true; + onFulfilled(value); + }, function (reason) { + if (done) return; + done = true; + onRejected(reason); + }) + } catch (ex) { + if (done) return; + done = true; + onRejected(ex); + } + } + + static all (promises) { + var accumulator = []; + var ready = SuperPromise.resolve(null); + + promises.forEach(function (promise, ndx) { + ready = ready.then(function () { + return promise; + }).then(function (value) { + accumulator[ndx] = value; + }); + }); + + return ready.then(function () { return accumulator; }); + } + + static race() {} + /* PART 3 */ static queue() { @@ -41,4 +164,7 @@ class SuperPromise { } } -module.exports = Promise; // TODO: kek +module.exports = SuperPromise; // TODO: kek + + + diff --git a/package.json b/package.json index d06ef53..8e13566 100644 --- a/package.json +++ b/package.json @@ -12,11 +12,11 @@ "task_2": "NODE_PATH=. node tasks/task_2.js", "task_3": "NODE_PATH=. node tasks/task_3.js", "task_4": "NODE_PATH=. node tasks/task_4.js", - "test_base": "part-1-task-2-test-1 lib/testPromise && npm run test_static", - "test_advanced": "part-1-task-2-test-2 lib/testPromise && npm run test_static", + "test_base": "part-1-task-2-test-1 lib/testPromise", + "test_advanced": "part-1-task-2-test-2 lib/testPromise", "test_static": "part-1-task-2-test-3 lib/testPromise", "test_bonus": "part-1-task-2-test-4 lib/testPromise", - "test": "npm run test_advanced && npm run test_bonus" + "test": "npm run test_advanced && npm run test_static && npm run test_bonus" }, "dependencies": { "part-1-task-2-test-1": "git://github.com/hse2016/part-1-task-2-test-1.git",