Open Linjiayu6 opened 4 years ago
// 接收多参
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)()
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
index = i
var fn = middleware[index]
var next = () => dispatch(i + 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(6)
})
app.use(async (ctx, next) => {
console.log(2)
await next()
console.log(5)
})
app.use(async (ctx, next) => {
console.log(3)
await next()
console.log(4)
})
app.start()
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()
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)
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))
dpr viewpoint media query
bfc
http get post
cache
last-modified IF modified SINCE
etag
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)
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) {
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)
概念
compose 函数组合
实现1 reduce / reduceRight
实现2 指针 + 递归