Я пытался всю ночь и не мог решить эту загадку.Код, который я хочу функционально реорганизовать:
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
AND html
в качестве ввода для записи записи в дб,но если я добавлю эту функцию в трубу после fetchHtml
, я получу только html
.И еще - функции в трубе должны быть одинарными.Должен ли я каким-то образом создать объект { url: 'http...', html: '<html>...' }
, прежде чем передать его в моем writeToCahce
?
2) Я хотел бы использовать функцию R.either, чтобы иметь возможность readFromCache
ИЛИ, если там нет успеха, перейти к моей выборкеиз веб-канала (который также сохранит HTML в БД).Но моя функция чтения из кеша возвращает Promise.Я мог бы использовать R.pipeP
, но, похоже, он не работает с either
(R.either
продолжается с первой функцией и возвращает ноль. Похоже, что он проверяет сам Promise и, поскольку это истинное значение, он дает мое обещание pipeP и там разрешаетсякак ноль (кеш пуст))
3) Я пытался играть с монадой задач, но с небольшим успехом.Я все еще новичок в этих понятиях
Мне кажется, я сделал что-то совершенно не так.Очень любопытно, как это можно сделать