首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >readFile同步节点

readFile同步节点
EN

Stack Overflow用户
提问于 2020-12-02 21:08:10
回答 1查看 47关注 0票数 0

我是nodejs的新手,刚刚开始学习。我需要读取5个json文件并将它们放在一个数组中。我创建了两个函数: readDirectory和processFile。

代码语言:javascript
复制
    let transactionArray = [];
    router.get('/', (req,res) => {
    
    //joining path of directory 
    const directoryPath = path.join(__dirname, '../data');
    
    readDirectory(directoryPath);
    
    res.send(JSON.stringify(transactionArray))
    
    })

readDirectory将获取dir并读取文件名。

代码语言:javascript
复制
    function readDirectory(directoryPath){
        //passsing directoryPath and callback function
    fs.readdir(directoryPath, function (err, files) {
        //handling error
        if (err) {
            return console.log('Unable to scan directory: ' + err);
        } 
        //listing all files using map
        let fileSummary = files.map(file => {
            
            //get the filename
            let categoryName = ''
    
            if (file.includes('category1')) {
                 categoryName = 'category1'
            } else if (file.includes('category2')) {
                 categoryName  = 'category2'
            } else {
                categoryName = 'Others'
            }
    
            // read the file
            const filePath = directoryPath +'/'+ file
    
            fs.readFile(filePath, 'utf8', (err, fileContents) => {
                if (err) {
                  console.error(err)
                  return
                }
                try {
                  let data = JSON.parse(fileContents, categoryName)
                  processFile(data, categoryName);
                   
                } catch(err) {
                    console.error(err)
                }
            })   
        }) 
    });    
    }

然后使用函数processFile读取文件。

代码语言:javascript
复制
function processFile(data, categoryName)
{
    let paymentSource = ''

    if (categoryName == 'category1'){
       paymentSource = categoryName +': '+ categoryName +' '+ data.currency_code
    } else if (categoryName == 'category2') {
        paymentSource = categoryName +': '+ data.extra.payer +'-'+ data.currency_code 
    } else {
        paymentSource = 'Others'
    }
    
    let transactionDetails = new Transaction(
        data.id,
        data.description,
        categoryName,
        data.made_on,
        data.amount,
        data.currency_code,
        paymentSource)

    transactionArray.push(transactionDetails)
console.log(transactionArray);
}

控制台日志如下所示:{Transaction1} {Transaction1}、{Transaction2}、{Transaction3}

但是UI上的结果只是[]

在调试期间,我注意到它没有同步读取,所以我尝试使用readFileSync,但它没有工作。如何同步读取这两个函数,这样就不会产生空数组了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-02 22:32:47

尝试一下,了解fs函数在回调时和同步时所做的事情。从您的代码中,我们做了一些更改,这样您就不必使用文件系统库中的同步函数了。

首先,您需要等待所有异步任务完成后才能返回响应。

代码语言:javascript
复制
router.get('/', async (req, res) => {
  // joining path of directory
  const directoryPath = path.join(__dirname, '../data')

  readDirectory(directoryPath).then(() => {
    res.send(JSON.stringify(transactionArray))
  }).catch(err => {
    res.status(500).json(err)
  })
})

其次,为了保持代码就像教你一些关于承诺的东西一样,让我们把第一个函数包装在一个承诺中。

代码语言:javascript
复制
function readDirectory (directoryPath) {
  return new Promise((resolve, reject) => {
    // passsing directoryPath and callback function
    fs.readdir(directoryPath, function (err, files) {
    // handling error
      if (err) {
        return console.log('Unable to scan directory: ' + err)
      }
      // listing all files using map
      const fileSummary = Promise.all(
       files.map(file => {
          return new Promise((resolve, reject) => {
          // get the filename
            let categoryName = ''

            if (file.includes('category1')) {
              categoryName = 'category1'
            } else if (file.includes('category2')) {
              categoryName = 'category2'
            } else {
              categoryName = 'Others'
            }

            // read the file
            const filePath = directoryPath + '/' + file

            fs.readFile(filePath, 'utf8', (err, fileContents) => {
              if (err) {
                console.error(err)
                reject(err)
              }
              try {
                const data = JSON.parse(fileContents, categoryName)
                processFile(data, categoryName).then(data => {
                  data()
                })
              } catch (err) {
                console.error(err)
                reject(err)
              }
            })
          })
        })
      ).then(() => {
        resolve()
      }).catch(err => {
        reject(err)
      })
    })
  })
}

有关承诺-> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise的javascript,请参阅圣经。

最后将processFile函数封装在一个承诺中

代码语言:javascript
复制
function processFile (data, categoryName) {
  return new Promise((resolve, reject) => {
    let paymentSource = ''

    if (categoryName == 'category1') {
      paymentSource = categoryName + ': ' + categoryName + ' ' + data.currency_code
    } else if (categoryName == 'category2') {
      paymentSource = categoryName + ': ' + data.extra.payer + '-' + data.currency_code
    } else {
      paymentSource = 'Others'
    }

    const transactionDetails = new Transaction(
      data.id,
      data.description,
      categoryName,
      data.made_on,
      data.amount,
      data.currency_code,
      paymentSource)

    transactionArray.push(transactionDetails)
    console.log(transactionArray)
    resolve()
  })
}

我到底在做什么?我只是让您的代码执行异步任务,但在继续之前等待它们完成。承诺是处理这件事的一种方法。您可以轻松地使用FS同步函数实现这一点,但是这样您就可以了解承诺!

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

https://stackoverflow.com/questions/65116155

复制
相关文章

相似问题

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