-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
14 - 函数式编程 #14
Comments
curry 多参数函数 变为 单一参数函数面试题: 如何实现 multi(2)(3, 4)= 24?// 接收多参
var add = (a, b, c) => a + b + c
// curry 接收单一参数
var add = a => b => c => a + b + c
var add = function (a) {
return function (b) {
return function (c) {
return a + b + c
}
}
}
// 如何实现
var curried = curry(add)
curried(1, 2, 3)()
curried(1, 2)(3)()
curried(1)(2)(3)() 都是一样的结果? 接收参数先保存, 再执行var add = (...args) => args.reduce((sum, cur) => sum += cur, 0)
function curry (executor) { // executor 最终执行函数
var _args = [] // 保存函数
return function fn (...args) {
if (args && args.length > 0) {
_args = _args.concat(args) // 接收参数
return fn // 递归下去
}
return executor.apply(this, _args) // 最终执行
}
}
curry(add)(1, 2)(3)(4, 5)()
curry(add)(1, 2, 3, 4, 5)()
curry(add)(1)(2, 3, 4, 5)()
curry(add)(1)(2, 3, 4)(5)() |
洋葱模型
|
KOA 洋葱模型 + 异步处理class Koa {
constructor () {
this.middleware = []
this.ctx = {}
}
use (fn) {
this.middleware.push(fn)
return this
}
/**
* 将所有函数组合在一起, 串联流程, 调用next才往下面执行
* c(b(a()))
* 先执行a, 通过调用next() koa内部派发 dispatch(i + 1), 继续下一个中间件
* 目标: 洋葱模型
*/
compose () {
var index = 0
var middleware = this.middleware
var ctx = this.ctx
function dispatch (i) {
if (i > middleware.length || i < 0) return
// 若最后一个中间件,返回一个 resolve promise, 必须返回这个要不然报错
if (i === middleware.length) return Promise.resolve()
index = i
var fn = middleware[index]
var next = () => dispatch(index + 1)
try {
return Promise.resolve(fn(ctx, next))
} catch (err) {
return Promise.reject(err)
}
}
dispatch(0)
}
start () {
this.compose()
}
}
var app = new Koa()
app.use(async (ctx, next) => {
console.log(1)
await next()
console.log(8)
})
app.use(async (ctx, next) => {
console.log(2)
let p = new Promise((resolve, roject) => {
setTimeout(() => {
console.log(3)
resolve(4)
}, 3000)
})
await p.then(data => console.log(data))
await next()
console.log(7)
})
app.use(async (ctx, next) => {
console.log(5)
await new Promise(resolve => setTimeout(() => resolve(1), 2000)).then()
await next()
console.log(6)
})
app.start() |
Generator + CO
主动推进function getData (arg) {
return new Promise(resolve => setTimeout(() => { resolve(arg + 1) }, arg * 1000))
}
function * generator (a) {
console.log('1', a)
var b = yield getData(a)
console.log('2', b)
var c = yield getData(b)
console.log('3', c)
var d = yield getData(c)
console.log('4', d)
return d
}
var g = generator(1)
function doing (...args) {
var { value, done } = g.next(...args)
if (done === true) {
return Promise.resolve(value)
}
return value.then(doing)
}
doing().then(console.log) co结合function getData (arg) {
return new Promise(resolve => setTimeout(() => { resolve(arg + 1) }, arg * 1000))
}
function * generator (a) {
console.log('1', a)
var b = yield getData(a)
console.log('2', b)
var c = yield getData(b)
console.log('3', c)
var d = yield getData(c)
console.log('4', d)
return d
}
function co (generator, ...args) {
return new Promise(resolve => {
var g = generator(...args)
function executor (...args1) {
var { value, done } = g.next(...args1)
if (done === true) return resolve(value)
return value.then((...args2) => executor(...args2))
}
executor()
})
}
// 必须是 Promise加持 才能 then 下去嘛
co(generator, 1).then(d => console.log('最后结果', d)) |
Open
dpr viewpoint media query |
异步串行处理 pipeline1. reducequeue.reduce((prev, next) => prev.then(d => next(d))) // 将上一个值返回传给下一个var A = args => new Promise(resolve => {
setTimeout(() => {
console.log('A', args)
resolve(1)
}, 1000)
})
var B = args => new Promise(resolve => {
setTimeout(() => {
console.log('B', args)
resolve(2)
}, 2000)
})
var C = args => new Promise(resolve => {
setTimeout(() => {
console.log('C', args)
resolve(3)
}, 3000)
})
var queue = [A, B, C]
function compose (queue, arg) {
return queue.reduce((prev, next) => prev.then(d => next(d)), Promise.resolve(arg))
}
compose(queue, 0) 2. dispatchvar A = args => new Promise(resolve => {
setTimeout(() => {
console.log('A', args)
resolve(1)
}, 1000)
})
var B = args => new Promise(resolve => {
setTimeout(() => {
console.log('B', args)
resolve(2)
}, 2000)
})
var C = args => new Promise(resolve => {
setTimeout(() => {
console.log('C', args)
resolve(3)
}, 3000)
})
var queue = [A, B, C]
function compose (queue) {
var _args1 = Array.prototype.slice.call(arguments, 1)
function dispatch (i) {
var _args2 = Array.prototype.slice.call(arguments, 1)
if (i === queue.length - 1) return Promise.resolve(queue[i](..._args2))
if (i < queue.length) {
return queue[i](..._args2).then((...d) => dispatch(i + 1, ...d))
}
}
dispatch(0, ..._args1)
}
compose(queue, 0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
概念
compose 函数组合
实现1 reduce / reduceRight
实现2 指针 + 递归
The text was updated successfully, but these errors were encountered: