2017-01-05 27 views
0

我很難讓一些異步操作的流程正確流動。由於我現在的代碼如下,outside readFile先打印到控制檯,然後打印namesyears,然後最後打印in readFile,當我希望整個readFile/forEach處理髮生在之前。如何使用節點fs構造異步流程

const fs = require('fs') 
const names = {} 
const years = {} 

fs.readdir('./namesData', (err, files) => { 
    files.forEach(file => { 
     var year = file.substr(3, 4) 
     var yearObj = {} 
     fs.readFile(`./namesData/${file}`, 'utf8', (err, data) => { 
      console.log('in readFile') 
      if (err) throw new Error(err) 
      var arr = data.split('\n') 
      arr.forEach(record => { 
       var recordArray = record.trim().split(',') 
       var name = recordArray[0] 
       var gender = recordArray[1] 
       var score = recordArray[2] 
       // populate 'names' object 
       var nameObj = {year: year, gender: gender, score: score} 
       if (names.hasOwnProperty(name)) { 
        names[name].push(nameObj) 
       } else { 
        names[name] = [nameObj] 
       } 
       // populate 'years' object & add to yearObj and then years object 
       var yearNameObj = {gender: gender, score: score} 
       if (yearObj.hasOwnProperty(name)) { 
        yearObj[name].push(yearNameObj) 
       } else { 
        yearObj[name] = [yearNameObj] 
       } 
      }) 
     }) 
     console.log('outside readFile') 
     years[year] = yearObj 
    }) 
    console.log(names) 
    console.log(years) 
}) 
+0

你能後的樣本數據是如何'years'和'會像names'? – Sridhar

回答

1

我試過這種方法。似乎足以滿足您在循環後打印names,years的需求。

'use strict'; 

let _ = require('lodash'); 
const fs = require('fs'); 

function readFile(file) { 
    try { 
    console.log('in readFile'); 
    return fs.readFileSync(`./namesData/${file}`, 'utf-8'); 
    } catch (err) { 
    console.log('err ', err.stack); 
    return ''; 
    } 
} 

fs.readdir('./namesData', (err, files) => { 
    let details = _.map(files, (file) => { 
    let data = readFile(file); 
    let year = file.substr(3, 4); 
    return _.map(data.split('\n'), (row) => { 
     if (_.isEmpty(row)) { 
     return; 
     } 
     let words = row.trim().split(','); 
     return { 
     year: year, 
     name: words[0], 
     gender: words[1], 
     score: words[2] 
     }; 
    }); 
    }); 
    console.log('names', _.groupBy(details, 'name')); 
    console.log('years', _.groupBy(details, 'year')); 
}); 

測試用硬編碼details陣列

let details = [{ 
    year: 1998, 
    name: 'A', 
    gender: 'M', 
    score: 20 
}, { 
    year: 1998, 
    name: 'B', 
    gender: 'M', 
    score: 21 
}, { 
    year: 1999, 
    name: 'A', 
    gender: 'M', 
    score: 100 
}, { 
    year: 1999, 
    name: 'A', 
    gender: 'M', 
    score: 80 
}]; 
+0

謝謝。我希望不使用任何同步fs方法;你認爲只用'fs.readFile()'可以重構嗎? – zahabba

+1

雅。你可以通過在一個promise中包裝'readFile()'來做到這一點。但是你需要調用'Promise.all()'。 'Promise.all()'是全部或全部。我保持同步版本,以避免增加複雜性。 – Sridhar