-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy path5-chain.js
More file actions
72 lines (60 loc) · 1.67 KB
/
5-chain.js
File metadata and controls
72 lines (60 loc) · 1.67 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
'use strict';
// Use list and chaining syntax to build sequence
const chain = (prev = null) => {
console.log('Create element');
const cur = () => {
console.log('Reverse from ' + (cur.fn ? cur.fn.name : 'null'));
if (cur.prev) {
cur.prev.next = cur;
cur.prev();
} else {
cur.forward();
}
};
cur.prev = prev;
cur.fn = null;
cur.args = null;
cur.do = (fn, ...args) => {
cur.fn = fn;
cur.args = args;
return chain(cur);
};
cur.forward = () => {
console.log('Forward');
if (cur.fn) cur.fn(...cur.args, (err, data) => {
console.log('Callback from ' + cur.fn.name);
console.dir({ data });
if (!err && cur.next) cur.next.forward();
else console.log('End at ' + cur.fn.name);
});
};
return cur;
};
// Emulate asynchronous calls
const wrapAsync = (fn) => (...args) => setTimeout(
() => fn(...args), Math.floor(Math.random() * 1000)
);
// Asynchronous functions
const readConfig = wrapAsync((name, callback) => {
console.log('(1) config loaded');
callback(null, { name });
});
const selectFromDb = wrapAsync((query, callback) => {
console.log('(2) SQL query executed');
callback(null, [{ name: 'Kiev' }, { name: 'Roma' } ]);
});
const getHttpPage = wrapAsync((url, callback) => {
console.log('(3) Page retrieved');
callback(null, '<html>Some archaic web here</html>');
});
const readFile = wrapAsync((path, callback) => {
console.log('(4) Readme file loaded');
callback(null, 'file content');
});
// Usage
const startChain = chain()
.do(readConfig, 'myConfig')
.do(selectFromDb, 'select * from cities')
.do(getHttpPage, 'http://kpi.ua')
.do(readFile, 'README.md');
startChain();