javascript - 将包含单个数据数组的任务链接(或映射)到任务数组

标签 javascript functional-programming monads folktale fantasyland

学习 Fanatasy Land/Folk Tale 的一部分引导我创建了一些代码。我本质上正在扫描我的网络(通过 someLib)并将结果上传到 mongo 存储库。扫描返回结果数组,而 upsert 到 mongo 需要独立处理结果(mongoose - 这也是我第一次使用这个库,所以我可能会弄错)。在传统的 promise 基本模型中,我会

// step 0: setup
const someLibPomise = makePromiseOf(someLib)

//set 1: get data
const dataArray = yield someLibPomise()

//set 2: convert to array of promises to upsert
const promiseArray = _.map(dataArray, makeUpsertPromise)

//step 3: wait on results
const upsertResults = yield promiseArray

就其本身而言,这是一个非常清晰的表示,但我想加深对这些功能技术的理解。我的工作版本还有一些不足之处,因为我似乎无法从 someLibTask 函数返回的任务中获取信息,该函数包含一个对象数组到代表各个 upsert 的任务数组。我觉得一定有更好的方法,这就是有效的方法:

// step 0: setup
const someLibTask = Async.liftNode(someLib)

const cleanUpData = (dataArray) => {
   return _.map(dataArray, (data) => { 
         // cleanup data object
         return data 
   })
}

const upsertTask = (collection) => {
    return (criteria, record) => {

        return new Task( (reject, resolve) => {
            const callback =  (error, data) => {
                if (error)  reject(error)
                else        resolve(data)
            }

            collection.findOneAndUpdate(criteria, record, 
                 {upsert: true}, callback)
        })

    }
}

const persist = (data) => {
    mongoose.connect('mongodb://localhost/db');
    const someUpsert = adapt.upsertTask(Some.collection)

    const tasks = _.map(data, (record) => {
        const criteria = { "id": record.id }
        return serverUpsert(criteria, record)
    })

    return Async.parallel(tasks).fork(console.error, process.exit)
}

// step 1: make a query and return an array of objects
// () => Task(object[]) 
const dataTask = someLibTask().map(cleanUpData)

// step 2: for the results to error log or persist method
// (d) => (), (d) => ()
dataTask.fork(console.error, persist)

理想情况下,我可以将 dataTask 的结果链接(或映射)到 persist 中,从而将该单个任务转换为 upsert 任务数组。然后我可以等待。我很想看到类似的东西:

// step 1: make a query and return an array of objects
const dataTask = someLibTask().map(cleanUpData)

// step 2: chain the results into upsert
const upsertTasks = dataTask.chain(persist)

//step 3: wait on the upsert tasks, and then log results
Async.parallel(upsertTasks).fork(console.error, process.exit)

最佳答案

get from a Task which contains an array of objects TO an array of Tasks

这是不可能的。您无法退出 Task monad。要了解该数组中将获得多少个任务,您需要首先运行初始任务。

你想要的似乎是

someLibTask().map(cleanUpData).chain(persist)

它返回所有更新插入结果的另一个任务。

关于javascript - 将包含单个数据数组的任务链接(或映射)到任务数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33899029/

相关文章:

javascript - 添加 ng-click 像属性 AngularJS

javascript - 如何使用服务更改范围变量?

javascript - Emacs 有问题的 JavaScript 缩进

java-8 - 使用 lambda 表达式的 int 回文

f# - F# 中的组合单子(monad)

scala - 如何实现读取器 monad 来访问数据库

Scala,Either[_,Seq[Either[_,T]] 到 Either[_,Seq[T]]

javascript - 为什么这个函数没有被调用?

functional-programming - 如何高效学习OCaml?

functional-programming - 在 SML 中优雅地打印二维数组