GithubHelp home page GithubHelp logo

14 - 函数式编程 about fe-notes HOT 6 OPEN

linjiayu6 avatar linjiayu6 commented on May 18, 2024
14 - 函数式编程

from fe-notes.

Comments (6)

Linjiayu6 avatar Linjiayu6 commented on May 18, 2024

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)()

from fe-notes.

Linjiayu6 avatar Linjiayu6 commented on May 18, 2024

洋葱模型

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()

from fe-notes.

Linjiayu6 avatar Linjiayu6 commented on May 18, 2024

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()

from fe-notes.

Linjiayu6 avatar Linjiayu6 commented on May 18, 2024

Generator + CO

  • g = fn(初始化值)
  • { value, done } = g.next()
  • value.then((data) => 函数(data))
    当done true, 则停止。

主动推进

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))

from fe-notes.

Linjiayu6 avatar Linjiayu6 commented on May 18, 2024

dpr viewpoint media query
bfc
http get post
cache
last-modified IF modified SINCE
etag

from fe-notes.

Linjiayu6 avatar Linjiayu6 commented on May 18, 2024

异步串行处理 pipeline

1. reduce

queue.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. dispatch

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)

from fe-notes.

Related Issues (16)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.