-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathcompose.js
65 lines (61 loc) · 1.73 KB
/
compose.js
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
// compose 函数特征:与 pipe 类似,只是执行顺序相反”从右向左“
// let funcs = [fn1, fn2, fn3, fn4]
// let composeFunc = compose(...funcs)
// // 相当于
// fn1(fn2(fn3(fn4(args))))
// compose函数实现
/** 1、递归实现 */
const compose = function(...args) {
let length = args.length
let count = length-1
let result
return function f1(...arg1) {
result = args[count].apply(this, arg1)
if(count <= 0) {
count = length - 1
return result
}
count--
return f1.call(null, result)
}
}
/**2、将函数数组反转,利用reduce实现(抖机灵) */
const reduceFunc = (f, g) => g.call(this, f.apply(this, arg))
const compose = (...args) => args.reverse().reduce(reduceFunc, args.shift())
/**3、reduce实现继续拓展,promise执行 */
const compose = function(...args) {
let init = args.pop()
return (...arg) =>
args.reverse().reduce((sequence, func) =>
sequence.then(result => func.call(null, result)),
Promise.resolve(init.apply(null, arg)))
}
/**4、lodash实现 */
const compose = function(funcs) {
const length = funcs.length;
let index = length;
// 判断funcs数组元素是否是函数
while(index--) {
if(typeof funcs[index] !== 'function') {
throw new TypeError('Expected a function')
}
}
return function(...args) {
let index = 0;
let result = length ? funcs.reverse()[index].apply(this, args) : args[0];
while(++index < length) {
result = funcs[index].apply(this, result);
}
return result;
}
}
/**5、redux实现 */
function compose(...funcs) {
if(funcs.length === 0) {
return arg => arg
}
if(funcs.length === 1) {
return funcs[0]
}
return funcs.reduce((a,b) => (...args) => a(b(...args)))
}