首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >partial.lenses:如何在光学和L.collect中使用异步操作?

partial.lenses:如何在光学和L.collect中使用异步操作?
EN

Stack Overflow用户
提问于 2018-11-16 07:35:27
回答 1查看 162关注 0票数 3

我知道,partial.lenses并不一定是解决以下问题的最佳方法,这也是问题的重点所在。我试图使用L.collect从partial.lenses库中列出目录中的文件。目标仅仅是获得一个扁平的文件名数组。

问题:我不使用fs.readdirSync,而是希望在我的光学中使用Node的fs API的异步版本,并承诺返回版本。

以下是readdir的增订本:

代码语言:javascript
复制
const util = require('util')
const fs = require('fs')
const readdirAsync = util.promisify(fs.readdir)

以下是实际实施情况。我想知道如何用异步版本替换readdir函数中的同步readdir

代码语言:javascript
复制
const L = require("partial.lenses")
const fs = require("fs")
const path = require("path")
const _ = require("lodash")

const basePath = path.basename(`${__dirname}/..`)

const isDirectory = dirent => {
  return dirent instanceof fs.Dirent ? dirent.isDirectory() : false
}

const readDir = path => () => {
  return fs.readdirSync(path, { withFileTypes: true })
}

const leafs = nodePath => {
  return L.cond(
    [
      _.isArray,
      L.lazy(() => [
        L.elems,
        L.choose(({ name }) => leafs(path.join(nodePath, name)))
      ])
    ],
    [
      isDirectory,
      L.lazy(() => [
        readDir(nodePath),
        L.elems,
        L.choose(({ name }) => leafs(path.join(nodePath, name)))
      ])
    ],
    [L.identity]
  )
}

const listFiles = async () =>
  L.collect(
    leafs(basePath),
    fs.readdirSync(basePath, { withFileTypes: true })
  )
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-16 07:58:27

这是一个有趣的问题,因为部分透镜可以处理这样的异步问题,但是这个库目前只提供了一点直接支持异步操作的直接支持。将来,这个库当然可以扩展,以便为执行异步操作提供更多的支持。

部分镜片中的横行构成应用操作。通过使用不同的应用程序,可以执行不同类型的操作,如收集元素、计算元素的最小值或计算数据结构的新版本。

许多操作,比如收集元素或计算最小值,都有一个底层的单样。任何一元,如数组级联

代码语言:javascript
复制
const ConcatArray = {empty: () => [], concat: (l, r) => l.concat(r)}

可以转换为应用程序。在部分镜头中,L.concatL.concatAs操作在内部完成。

因此,为了异步地收集元素,我们可以使用连接单子的异步版本。我们可以通过创建一个函数来实现这个目标,该函数可以将任何monoid转换为异步monoid:

代码语言:javascript
复制
const asyncMonoid = m => ({
  empty: async () => m.empty(),
  concat: async (l, r) => m.concat(await l, await r)
})

现在我们可以定义异步版本的L.collect,如下所示:

代码语言:javascript
复制
const collectAsync = L.concatAs(
  async x => [x],
  asyncMonoid(ConcatArray)
)

为了解决这个问题,我们还需要一种方法来获得异步操作的结果,这样我们就可以用光学放大它。为此,我们可以定义一个新的原始光学函数,它等待焦点在光学合成中向前传递:

代码语言:javascript
复制
const awaitIt = async (x, i, F, xi2yF) => xi2yF(await x, i)

使用上面的awaitIt光学函数,我们现在可以定义文件系统中文件的异步遍历,给出一个适当的异步readDirectory函数:

代码语言:javascript
复制
const filesUnderEntries = L.lazy(() => [
  awaitIt,
  L.elems,
  L.ifElse(L.get('isDir'), ['path', filesUnderDirectory], 'path')
])

const filesUnderDirectory = [L.reread(readDirectory), filesUnderEntries]

我们可以使用上面的遍历来检查目录结构并从中选择文件。我们还可以进一步组合操作来读取这些文件并检查这些文件中的数据。例如

代码语言:javascript
复制
collectAsync(
  [
    filesUnderDirectory,
    L.when(R.test(/\.my$/)),
    L.reread(readFile),
    awaitIt
  ]
)

定义一个异步操作,该操作遍历目录树并在目录树下生成具有.my扩展名的文件的内容。

这是一个使用完整代码和示例的游乐场使用伪造的文件系统操作。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53333345

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档