在这里,我们尝试使用 javascript 以功能方式进行大量调用,问题是我们最终得到 Reader.of(Task.of(Reader.of(Task.of))),所以我们需要映射(map(map(map))) 我们需要操作的值。
计算需要转到 DynamoDB 表,获取特定属性,然后再次转到 DynamoDB 并获取另一个属性,然后转到 facebook api 获取集合,最后将该信息存储在 Dynamo 中的表中。因此,每个调用都使用 AWS javascript 插件和 node.js 中的 facebook 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})