为了账号安全,请及时绑定邮箱和手机立即绑定

如何在处理HTTP请求之前将CSV文件同步加载到内存中

如何在处理HTTP请求之前将CSV文件同步加载到内存中

繁花不似锦 2021-04-06 13:09:47
我正在尝试编写一个简单的express / node.js应用,该应用使用在csv文件中找到的数据来响应GET请求。我想阅读此csv文件以生成javascript对象(本质上是键-值映射),然后使生成的映射可用于控制器中的HTTP请求处理逻辑。我编写了一个读取csv文件并导出所需对象的模块,但是我不确定如何确保:该操作完成,并且对象实际存在,然后处理HTTP请求服务器启动时,文件操作仅执行一次,而每个请求仅执行一次,不会产生大量开销如何在快速应用程序的上下文中组织代码以实现这些目标?这就是我处理CSV文件的方式:var myMap = {};fs.createReadStream('filename.csv')    .pipe(csv())  .on('data', (row) => {    // Build javascript object    myMap[row['key']] = row['value'];  })  .on('end', () => {    console.log('Done.');  });// Does this work?module.exports =  myMap;
查看完整描述

3 回答

?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

如何确保将文件加载到内存中之后http对象进行侦听:



// server.js

var myMap = {};


function readCsv(cb){

  fs.createReadStream('filename.csv')  

  .pipe(csv())

  .on('data', (row) => {

    // Build javascript object

    myMap[row['key']] = row['value'];

  })

  .on('end', () => {

    console.log('Done.');

    cb();

  });

}


var app = express();


exports = Object.freeze({

  server: http.createServer(app)

  init(){

    readCsv(() => {

      this.server.listen(80)

    })

  }

})


这样的事情。


您还可以利用Promise


// server.js

var myMap = {};


function readCsv(){

  return new Promise((resolve, reject) => {

    fs.createReadStream('filename.csv')  

    .pipe(csv())

    .on('data', (row) => {

      // Build javascript object

      myMap[row['key']] = row['value'];

    })

    .on('end', () => {

      console.log('Done.');

      resolve();

    })

    .on('error', reject)

  })


}


var app = express();


exports = Object.freeze({

  server: http.createServer(app)

  init(){

    return readCsv().then(() => {

      this.server.listen(80)

    })

  }

})


查看完整回答
反对 回复 2021-04-08
?
繁花如伊

TA贡献2012条经验 获得超12个赞

我会寻找一种更同步的方式来读取文件和处理http请求。这是它的外观示例代码,


import fs from 'fs';


async function processCSV() {

    try {

        let map = await readCsv();

        //handle http request in another function with same async await way

        let http = await processHttpRequest(map);


        // process  the http response

    } catch (e) {

        console.log('e', e);

    }


}


function readCsv()

{

    let myMap = [];

    fs.createReadStream('filename.csv')

        .pipe(csv())

        .on('data', (row) => {

            // Build javascript object

           return myMap[row['key']] = row['value'];

        })

        .on('end', () => {

            console.log('Done.');

        });

}

async function processHttpRequest(map)

{

    try

    {

        let reqres = await httpReuqest(map); // Your defined function for httpReuqest

    }

    catch (e)

    {


    }


}

processCSV();

processHttpReuqet();


查看完整回答
反对 回复 2021-04-08
?
函数式编程

TA贡献1807条经验 获得超9个赞

为了实现您的两个目标,您可以将代码包含在app.js文件中。App.js仅在快递服务器启动时运行。页面刷新时不会重新加载。您可以在读取流结束后运行app.listen。


var myMap = {};


fs.createReadStream('filename.csv')  

  .pipe(csv())

  .on('data', (row) => {

    // Build javascript object

    myMap[row['key']] = row['value'];

  })

  .on('end', () => {

    app.listen(port, () => console.log(`Example app listening on port ${port}!`));

  });

但是,由于我认为您不会有大量数据,因此最好对csv解析器和文件阅读器都使用同步(阻塞)方法。这只是使它更容易理解。我在下面使用csv-parse。


const express = require('express')

const fs = require('fs')

const parse = require('csv-parse/lib/sync')


const app = express()

const port = 3000


/* In this example assume myMap will be

/ `

/ "key_1","key_2"

/ "value 1","value 2"

/ `

*/

var myMap = fs.readFileSync('sample.csv', 'utf8');


/* parsing the csv will return:

/  [Object {key_1: "value 1", key_2: "value 2"}]

*/

const records = parse(myMap, {

  columns: true,

  skip_empty_lines: true

})


app.get('/', (req, res) => res.send('Hello World!' + records[0].key_1))

app.listen(port, () => console.log(`Example app listening on port ${port}!`))


查看完整回答
反对 回复 2021-04-08
  • 3 回答
  • 0 关注
  • 202 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信