Spa*_*ers 9 javascript functional-programming ramda.js folktale fantasyland
所以我开始关注Ramda/Folktale.我在尝试映射来自目录的任务数组时遇到问题.我正在尝试解析文件内容.
var fs = require('fs');
var util = require('util');
var R = require('ramda');
var Task = require('data.task');
var compose = R.compose;
var map = R.map;
var chain = R.chain;
function parseFile(data) {
console.log("Name: " + data.match(/\$name:(.*)/)[1]);
console.log("Description: " + data.match(/\$description:(.*)/)[1]);
console.log("Example path: " + data.match(/\$example:(.*)/)[1]);
}
// String => Task [String]
function readDirectories(path) {
return new Task(function(reject, resolve) {
fs.readdir(path, function(err, files) {
err ? reject(err) : resolve(files);
})
})
}
// String => Task String
function readFile(file) {
return new Task(function(reject, resolve) {
fs.readFile('./src/less/' + file, 'utf8', function(err, data) {
err ? reject(err) : resolve(data);
})
})
}
var app = compose(chain(readFile), readDirectories);
app('./src/less').fork(
function(error) { throw error },
function(data) { util.log(data) }
);
Run Code Online (Sandbox Code Playgroud)
我正在读取目录中的文件并返回一个Task.当这个解决时,它应该进入readFile函数(返回一个新任务).一旦它读取文件,我希望它只是从那里解析一些位.
具有以下内容:
var app = compose(chain(readFile), readDirectories);
Run Code Online (Sandbox Code Playgroud)
它进入了readFile函数,但'file'是一个文件数组,因此它出错.
附:
var app = compose(chain(map(readFile)), readDirectories);
Run Code Online (Sandbox Code Playgroud)
我们永远不会进入fs.readfile(),但'file'是实际的文件名.
我对此非常感到困惑,文档令人费解.欢迎任何建议.
谢谢
dav*_*ers 11
'use strict';
const fs = require('fs');
const Task = require('data.task');
const R = require('ramda');
// parseFile :: String -> { name :: String
// , description :: String
// , example :: String }
const parseFile = data => ({
name: R.nth(1, R.match(/[$]name:(.*)/, data)),
description: R.nth(1, R.match(/[$]description:(.*)/, data)),
example: R.nth(1, R.match(/[$]example:(.*)/, data)),
});
// readDirectories :: String -> Task (Array String)
const readDirectories = path =>
new Task((reject, resolve) => {
fs.readdir(path, (err, filenames) => {
err == null ? resolve(filenames) : reject(err);
})
});
// readFile :: String -> Task String
const readFile = filename =>
new Task(function(reject, resolve) {
fs.readFile('./src/less/' + filename, 'utf8', (err, data) => {
err == null ? resolve(data) : reject(err);
})
});
// dirs :: Task (Array String)
const dirs = readDirectories('./src/less');
// files :: Task (Array (Task String))
const files = R.map(R.map(readFile), dirs);
// sequenced :: Task (Task (Array String))
const sequenced = R.map(R.sequence(Task.of), files);
// unnested :: Task (Array String)
const unnested = R.unnest(sequenced);
// parsed :: Task (Array { name :: String
// , description :: String
// , example :: String })
const parsed = R.map(R.map(parseFile), unnested);
parsed.fork(err => {
process.stderr.write(err.message);
process.exit(1);
},
data => {
process.stdout.write(R.toString(data));
process.exit(0);
});
Run Code Online (Sandbox Code Playgroud)
我在一个单独的行上编写了每个转换,因此我可以包含类型签名,使嵌套映射更容易理解.这些当然可以组合成一个管道R.pipe.
最有趣的步骤是使用R.sequence转换Array (Task String)为Task (Array String)和R.unnest转换Task (Task (Array String))为Task (Array String).
如果您还没有这样做,我建议看一下格子/异步问题.