繁体   English   中英

如何重构该命令式JS的功能?

[英]How to refactor this imperative JS to be functional?

我整夜都在努力,无法解决这个难题。 我想以功能方式重构代码:

const R = require('ramda')
const axios = require('axios')
const Datastore = require('nedb')

const getDatastore = R.always(
  new Datastore({ filename: './cache.nedb', autoload: true }),
)

const writeHtmlToCache = R.curry((db, url, html) => {
  return new Promise((resolve, reject) => {
    db.insert({ url, html }, (err, doc) => {
      if (err) return reject(err)
      resolve(doc)
    })
  })
})

const readHtmlFromCache = R.curry((db, url) => {
  return new Promise((resolve, reject) => {
    db.findOne({ url }, (err, doc) => {
      if (err) reject(err)
      else resolve(doc)
    })
  })
})

const app = async url => {
  const db = getDatastore()
  let html = R.prop('html', await readHtmlFromCache(db, url))
  if (html) {
    console.log('loaded from cache', html.length)
    return html
  } else {
    html = R.prop('data', await axios.get(url))
    writeHtmlToCache(db, url, html)
    console.log('loaded from web', html.length)
    return html
  }
}

app('http://example.org/')

我遇到的问题:1)在writeToCache函数中,我需要urlhtml作为输入来将记录写入db,但是如果我将此函数放在fetchHtml之后的管道中,则fetchHtml得到html 还有-管道中的功能应该是一元的。 我应该以某种方式使对象{ url: 'http...', html: '<html>...' }之前将其传递给我的writeToCahce吗?

2)我想使用R.function能够readFromCache或如果那里没有成功,请从Web管道中获取我的信息(它也会将html保存在db中)。 但是我的缓存读取功能返回Promise。 我可以使用R.pipeP但似乎either R.eitherR.either继续执行第一个函数并返回null。似乎它测试Promise本身,并且它是真实值,它给了我对pipeP的承诺,并且在那里将其解析为null (缓存为空))

3)我尝试与Task monad一起玩,但没有取得很大的成功。 我对这些概念还是陌生的

我觉得自己做错了什么。 很好奇如何做到

我会用一些来自下蹲的帮手以及关闭的魔力

import unless from 'crocks/logic/unless'
import composeP from 'crocks/combinators/composeP'

const getDataWithUrl = url => () =>
  axios.get(url).then(R.prop('data')))

const writeWithDbAndUrl = (db, url) => html =>
  writeHtmlToCache(db, url, html)

const writeWhenNoHtml = (db, url) =>
  composeP(writeWithDbAndUrl(db, url), getDataWithUrl(url))

const app = url => {
  const db = getDatastore()
  return readHtmlFromCache(db, url)
    .then(unless(R.prop('html'), writeWhenNoHtml(db, url))
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM