[英]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
函数中,我需要url
和html
作为输入来将记录写入db,但是如果我将此函数放在fetchHtml
之后的管道中,则fetchHtml
得到html
。 还有-管道中的功能应该是一元的。 我应该以某种方式使对象{ url: 'http...', html: '<html>...' }
之前将其传递给我的writeToCahce
吗?
2)我想使用R.function能够readFromCache
或如果那里没有成功,请从Web管道中获取我的信息(它也会将html保存在db中)。 但是我的缓存读取功能返回Promise。 我可以使用R.pipeP
但似乎either
R.either
( R.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.