-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsync-node.js
More file actions
134 lines (122 loc) · 3.13 KB
/
Copy pathsync-node.js
File metadata and controls
134 lines (122 loc) · 3.13 KB
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
122
123
124
125
126
127
128
129
130
131
132
133
134
require("object.observe");
(function () {
/**
* ----------- Helper functiosn --------------
*/
function pushJob (queue, job) {
var monitorObject = {
job: job,
isResolved : null,
response: null
}
queue.push(monitorObject);
return new Promise(function (resolve, reject) {
function observerFunction() {
if (monitorObject.isResolved!=null) {
Object.unobserve(monitorObject, observerFunction);
if(monitorObject.isResolved===true){
resolve(monitorObject.response);
}
else{
reject(monitorObject.response);
}
}
}
Object.observe(monitorObject, observerFunction);
});
}
/**
* ------------------ Apis -------------------
*/
/**
* SyncNode constructor
*/
var SyncNode = function (obj) {
obj = obj || {};
this.timeout = obj.timeout;
this.syncTaskPointer = null;
this.jobQueue = [];
this.lastResponse = {
res:null,
err:null,
}
this.isRunning = false;
this.observer = null;
this._observerResolve = null;
}
/**
* push a new job at the end of the job queue
* The input `job` can be of multiple types
* @param {Function} job [the function to be executed]
* @return {Object} [{jobId, promise}]
*/
SyncNode.prototype.pushJob = function (job) {
var returnObj = null;
if(job){
if(typeof job === "function"){
returnObj = pushJob(this.jobQueue, job);
this.checkAndStartGenerator();
}
}
return returnObj;
}
/**
* to check if the generator is started and everually start it
* @return {Void}
*/
SyncNode.prototype.checkAndStartGenerator = function() {
if(this.jobQueue.length==1 && !this.syncTaskPointer){
this.stepAhead();
}
}
/**
* The helps to move ahed the current pointer.
* It's exposed as api as sometime the person using the library may want a force stepAhead
* @return {Object} GeneratorValue
*/
SyncNode.prototype.stepAhead = function () {
if(!this.syncTaskPointer){
this.isRunning = true;
this.observer = new Promise((resolve, reject)=>{
this._observerResolve = resolve;
});
this.syncTaskPointer = this.syncTaskRunner(this.jobQueue);
}
return this.syncTaskPointer.next();
}
/**
* This is the generator to make things synchronous
* @yield {Object} returns a generator object
*/
SyncNode.prototype.syncTaskRunner = function* () {
var jobQueue = this.jobQueue;
while (jobQueue.length > 0) {
var jobObj = jobQueue.shift();
yield this.taskHandler(jobObj);
}
this.syncTaskPointer = null;
this.isRunning = false;
this._observerResolve(this.lastResponse.res);
}
SyncNode.prototype.taskHandler = function(jobObj) {
var response = jobObj.job(this.lastResponse.res, this.lastResponse.err);
Promise.resolve(response).then(function (data) {
jobObj.isResolved = true;
jobObj.response = data;
this.lastResponse.err=null;
this.lastResponse.res=data;
this.syncTaskPointer.next();
}.bind(this), function (err) {
jobObj.isResolved = false;
jobObj.response = err;
this.lastResponse.err=err;
this.lastResponse.res=null;
this.syncTaskPointer.next();
}.bind(this));
}
module.exports = {
createQueue: function () {
return new SyncNode();
}
}
})();