8

Zacząłem więc przeglądać Ramdę/Folktale. Wystąpił problem podczas próby mapowania na szereg zadań pochodzących z katalogu. Próbuję parsować zawartość pliku.Mapowanie tablicy zadań w JavaScript

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) } 
); 

Czytam pliki w katalogu i zwracam zadanie. Gdy to rozwiąże, powinno przejść do funkcji readFile (która zwraca nowe zadanie). Po przeczytaniu pliku chcę, aby po prostu przeanalizował niektóre kawałki.

z następującymi:

var app = compose(chain(readFile), readDirectories); 

To staje się funkcją readfile ale „Plik” jest tablicą plików więc błędów.

Z:

var app = compose(chain(map(readFile)), readDirectories); 

Nigdy nie dostać się fs.readfile(), ale 'plik' jest rzeczywista nazwa pliku.

Jestem dość zaskoczony, a dokumentacja jest kłopotliwa. Wszelkie sugestie mile widziane.

Dzięki

Odpowiedz

9
'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); 
      }); 

pisałem każdej z przemian w osobnej linii, więc może zawierać podpisy typu, które sprawiają, zagnieżdżone mapy łatwiejsze do zrozumienia. Można je oczywiście połączyć w potok za pośrednictwem R.pipe.

Najciekawsze kroki korzystania R.sequence przekształcić w Task (Array String)Array (Task String) i używając R.unnest przekształcić Task (Task (Array String)) do Task (Array String).

Proponuję przejrzeć plaid/async-problem, jeśli jeszcze tego nie zrobiłeś.

+1

Dzięki. To naprawdę ciekawe. To taka zmiana myślenia, z którą się zmagałem. Powrót do książki Dr Boolean. – SpaceBeers

+0

Nie mogę znaleźć dojazdu do pracy w dokumentacji ramda. czego mi brakuje? – akaphenom

+0

także (skoro nie mogę znaleźć dokumentacji), jak przebiega droga do pracy inna niż funkcja sekwencji "control.monads"? – akaphenom

4

Zgodnie z sugestią Davida, commute jest przydatna do przekształcenia listy niektórych aplikacji (takich jak Task) w pojedynczy aplikator zawierający listę wartości.

var app = compose(chain(map(readFile)), readDirectories);

Nigdy nie dostać się fs.readfile(), ale 'plik' jest rzeczywista nazwa pliku.

blisko spokrewniony commuteMap może pomóc tutaj też jak będzie dbać o odrębnym etapie map, co oznacza kod powyżej powinny również być w stanie przedstawić jako:

var app = compose(chain(commuteMap(readFile, Task.of)), readDirectories); 
+0

To świetnie. Dzięki. – SpaceBeers

0

miałem podobny problem czytać wszystkie pliki w katalogu i rozpoczął ramda za pipeP:

'use strict'; 

const fs = require('fs'); 
const promisify = require("es6-promisify"); 
const _ = require('ramda'); 

const path = './src/less/'; 
const log = function(x){ console.dir(x); return x }; 
const map = _.map; 
const take = _.take; 

const readdir = promisify(fs.readdir); 
const readFile = _.curry(fs.readFile); 
const readTextFile = readFile(_.__, 'utf8'); 
const readTextFileP = promisify(readTextFile); 

var app = _.pipeP(
    readdir, 
    take(2), // for debugging, so don’t waste time reading all the files 
    map(_.concat(path)), 
    map(readTextFileP), 
    promiseAll, 
    map(take(50)), 
    log 
); 

function promiseAll(arr) { 
    return Promise.all(arr) 
} 

app(path); 

Promise.all wydaje się być wymagane podczas odczytu plików jako pipeP oczekuje wartości lub AP romise, ale otrzymuje szereg obietnic do odczytania plików. To, co mnie zastanawia, to dlatego, że musiałem wykonać funkcję zwracającą Promise.all zamiast ją podpinać.

Twoje użycie zadania/widelca jest intrygujące, ponieważ wbudowana jest obsługa błędów. Chciałoby, żeby pipeP miał blok catch, ponieważ bez niego trzeba wstrzyknąć, co jest trudne dla początkującego, takiego jak ja, aby to naprawić.

Powiązane problemy