-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.js
More file actions
104 lines (93 loc) · 2.5 KB
/
utils.js
File metadata and controls
104 lines (93 loc) · 2.5 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
export const isDefined = val => val != null
export const isFunction = val => typeof val === 'function'
export const noop = _ => { }
export const newScript = (src) => (cb) => {
const scriptElem = document.createElement('script')
if (typeof src === 'object') {
// copy every property to the element
for (var key in src) {
if (Object.prototype.hasOwnProperty.call(src, key)) {
scriptElem[key] = src[key];
}
}
src = src.src;
} else {
scriptElem.src = src
}
scriptElem.addEventListener('load', () => cb(null, src))
scriptElem.addEventListener('error', () => cb(true, src))
document.body.appendChild(scriptElem)
return scriptElem
}
const keyIterator = (cols) => {
const keys = Object.keys(cols)
let i = -1
return {
next () {
i++ // inc
if (i >= keys.length) return null
else return keys[i]
}
}
}
// tasks should be a collection of thunk
export const parallel = (...tasks) => (each) => (cb) => {
let hasError = false
let successed = 0
const ret = []
tasks = tasks.filter(isFunction)
if (tasks.length <= 0) cb(null)
else {
tasks.forEach((task, i) => {
const thunk = task
thunk((err, ...args) => {
if (err) hasError = true
else {
// collect result
if (args.length <= 1) args = args[0]
ret[i] = args
successed ++
}
if (isFunction(each)) each.call(null, err, args, i)
if (hasError) cb(true)
else if (tasks.length === successed) {
cb(null, ret)
}
})
})
}
}
// tasks should be a collection of thunk
export const series = (...tasks) => (each) => (cb) => {
tasks = tasks.filter(val => val != null)
const nextKey = keyIterator(tasks)
const nextThunk = () => {
const key = nextKey.next()
let thunk = tasks[key]
if (Array.isArray(thunk)) thunk = parallel.apply(null, thunk).call(null, each)
return [ +key, thunk ] // convert `key` to number
}
let key, thunk
let next = nextThunk()
key = next[0]
thunk = next[1]
if (thunk == null) return cb(null)
const ret = []
const iterator = () => {
thunk((err, ...args) => {
if (args.length <= 1) args = args[0]
if (isFunction(each)) each.call(null, err, args, key)
if (err) cb(err)
else {
// collect result
ret.push(args)
next = nextThunk()
key = next[0]
thunk = next[1]
if (thunk == null) return cb(null, ret) // finished
else iterator()
}
})
}
iterator()
}