Использование монад задач и читателей в JavaScript (DynamoDB и Facebook API)

Здесь мы пытаемся сделать много вызовов функциональным способом с помощью javascript, проблема в том, что в итоге мы получаем Reader.of(Task.of(Reader.of(Task.of)))), поэтому нам нужно отобразить (map(map(map))) значения, которые нам нужны для работы.

Вычисления должны перейти к таблице DynamoDB, получить определенное свойство, затем снова перейти к DynamoDB и получить другое свойство, после этого перейдите в api facebook, чтобы получить коллекцию, и, наконец, сохранить эту информацию в таблице в Dynamo. Таким образом, каждый из этих вызовов использует плагин javascript AWS и плагин Graph Graph в ноде. Таким образом, нам нужно передать зависимость AWS от запуска, а затем нам нужно форкнуть, затем снова пройти AWS и снова форкать, затем снова передать FBGraph при запуске и снова форк, это довольно утомительно, если вы строите вычисления.

В любом случае вот код:

require('pointfree-fantasy').expose(global)
import Reader from 'fantasy-readers'
import Task from 'data.task'
import _ from 'ramda'


const log = x => {console.log(x); return x}

const ReaderTask = Reader.ReaderT(Task)

// scan :: string -> [a]
const scan = x => Reader.ask.map(env => env.aws.scanAsync({tableName: x}))

// batchGetItems :: [a] -> [b]
const batchGetItem = x => Reader.ask.map(env => env.aws.batchGetItemAsync(x))

// batchWriteItem :: [a] -> [b]
const batchWriteItem = x => Reader.ask.map(env => env.aws.batchWriteItemAsync(x))

// scanCampaigns :: null -> [a]
const scanCampaigns = () => scan('CampaignStats')

const FBBatchGetItem = x => Reader.ask.map(env => env.fb.batchAsync(x))

const getCampaigns = compose(scanCampaigns, Reader.of)

const groupUsers = _.groupBy(x => x.user_fbid)

const batchGetAccessToken = chain(batchGetItem, ReaderTask.of)

const getCampaignsInsights = chain(FBBatchGetItem, ReaderTask.of)

const saveInsights = chain(batchWriteItem, ReaderTask.of)

const updateCampaignStats = chain(batchWriteItem, ReaderTask.of)

const taskOfEvery = (Task, num) => compose(map(Task.of),_.splitEvery(num))

const runTaskWithFn = (fn, task) => fn(task.fork(err => 'err', x => x))

const filterActive = _.filter(x => x.active === 'true')

const getItems = x => x.Items

const groupAndFilter = compose(groupUsers, filterActive, getItems)

// filterByLastFetch :: ([a], string) => [a]
const filterByLastFetch = (x, y) => x.filter(x => x.last_fetch < y)

export {getCampaigns, batchGetAccessToken, getCampaignsInsights, saveInsights,
        groupUsers,filterByLastFetch, updateCampaignStats, taskOfEvery,
        runTaskWithFn, filterActive, groupAndFilter,
        getItems}

Цель состоит в том, чтобы передать плагин AWS и плагин FBGraph только один раз для вычисления, чтобы создать элегантную композицию, такую ​​как:

const computation = compose(saveIntoDynamo3, fetchFromFacebook,fetchFromDynamo2,fetchFromDynamo)

а потом:

computation().run({aws: AWSService, FB: FBGraph})

0 ответов

Другие вопросы по тегам