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

我正在尝试编写一个简单的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;


繁花不似锦
浏览 204回答 3
3回答

人到中年有点甜

如何确保将文件加载到内存中之后http对象进行侦听:// server.jsvar 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.jsvar 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)    })  }})

繁花如伊

我会寻找一种更同步的方式来读取文件和处理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();

函数式编程

为了实现您的两个目标,您可以将代码包含在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}!`))
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript