Node.js ||如何编写文件,一旦完成编写就读取它?

时间:2017-09-09 08:10:37

标签: javascript json node.js

我对node.js相当新,我还在学习编码方式 以下是我想要完成的事情......

[*]从api请求数据。

[*]将数据写入新的JSON文件。

[*]阅读新写的文件。

[*]提取具体信息。

到目前为止,这就是我的目标

let     request = require('request'),
        fs = require('fs'),
        DATA = require('./DATA.json'),
        url = "https://dataThatIAmTryingToGet";


        request(url, (error, response, body)=> {
          if (!error && response.statusCode === 200) {
            fs.writeFile("./DATA.json", (body))
          } else {
            console.log("Got an error: ", error, ", status code: ", response.statusCode)
          }
        });

        if (fs.existsSync("./DATA.json")){
            fs.readFile("./DATA.json", (err, data) => {
                if (err) {
                    console.log("Whoopsiedaisy");
                } else {
                    console.log("You did it nerd");
                    console.log(DATA.response.items.length);
                }
            })
        };

使用此代码,我完成了我的清单中的前两个...

[X]从api请求数据。

[X]将数据写入新的JSON文件。

[*]阅读新写的文件。

[*]提取具体信息。

控制台正在打印You did it nerd,但我得到的错误是console.log(DATA.response.items.length);在控制台中返回undefined。我试图看看api中有多少具体项目属于items。 (下面的api示例)。我的问题是我不确定是不是因为文件读取速度太快,或者我试图错误地读取数据。

这是api输出的一个例子......

{
    "response": {
        "success": 1,
        "current_time": 1488743993,
        "raw_usd_value": 0.1,
        "usd_currency": "coins",
        "usd_currency_index": 5002,
        "items": {
            "Item 1": {
                "defindex": [
                    5002
                ],
                "prices": {
                    "6": {
                        "Tradable": {
                            "Craftable": [
                                {
                                    "value": 0.08,
                                    "currency": "usd",
                                    "difference": 0,
                                    "last_update": 1488385886,
                                    "value_high": 0.12
                                }
                            ]
                        }
                    }
                }
            },
            "Item 2": {
                "defindex": [
                    5021
                ],
                "prices": {
                    "6": {
                        "Tradable": {
                            "Craftable": [
                                {
                                    "value": 14,
                                    "currency": "usd",
                                    "difference": 14.11,
                                    "last_update": 1488385975,
                                    "value_high": 14.22
                                }
                            ]
                        }
                    }
                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

我会使用承诺来完成这些任务。这将使任务的顺序非常清晰,并且您可以轻松读取代码而无需许多嵌套回调。在下面的示例中,我使用bluebird作为承诺,但您可以实施" promisification"如果你坚持的话,为自己。下面将执行您想要的操作(不需要检查fs.existsSync,如果文件不存在,则只会在fs.readFile中抛出错误,您可以在catch处理。

小旁注:response.items.length返回undefined,因为items是您案例中的一个对象,它没有length属性。我想你已经将它与数组混合了。

const Promise = require('bluebird');
const request = Promise.promisifyAll(require('request'));
const fs = Promise.promisifyAll(require('fs'));
const url = 'http://localhost:3000';

request.getAsync(url)
  .then(data => fs.writeFileAsync("output.json", data.body))
  .then(() => fs.readFileAsync("output.json", "UTF-8"))
  .then(data => console.log(JSON.parse(data).response))
  .catch(err => console.log(err));

这是一个简单的模拟服务器,只返回您发布的数据:

/* MOCK SERVER */
const http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'application/json'});
  res.end(JSON.stringify({
      "response": {
        "success": 1,
        "current_time": 1488743993,
        "raw_usd_value": 0.1,
        "usd_currency": "coins",
        "usd_currency_index": 5002,
        "items": {
          "Item 1": {
            "defindex": [
              5002
            ],
            "prices": {
              "6": {
                "Tradable": {
                  "Craftable": [
                    {
                      "value": 0.08,
                      "currency": "usd",
                      "difference": 0,
                      "last_update": 1488385886,
                      "value_high": 0.12
                    }
                  ]
                }
              }
            }
          },
          "Item 2": {
            "defindex": [
              5021
            ],
            "prices": {
              "6": {
                "Tradable": {
                  "Craftable": [
                    {
                      "value": 14,
                      "currency": "usd",
                      "difference": 14.11,
                      "last_update": 1488385975,
                      "value_high": 14.22
                    }
                  ]
                }
              }
            }
          }
        }
      }
    })
  );
}).listen(3000);

/* END MOCK */

答案 1 :(得分:0)

您正在编写文件异步。这意味着它将调用fs.writeFile但是继续而不等待它完成。因为写入文件系统需要[非常少]的时间,程序会在fs.writeFile仍在进行时调用其余代码。

要解决此问题,只需将其余代码放入fs.writeFile

的回调中

希望这是有道理的。请参阅下面的固定代码:

let request = require('request'),
  fs = require('fs'),
  DATA = require('./DATA.json'),
  url = "https://dataThatIAmTryingToGet";


request(url, (error, response, body) => {
  if (!error && response.statusCode === 200) {
    fs.writeFile("./DATA.json", (body), function () {
      if (fs.existsSync("./DATA.json")) {
        fs.readFile("./DATA.json", (err, data) => {
          if (err) {
            console.log("Whoopsiedaisy");
          } else {
            console.log("You did it nerd");
            console.log(DATA.response.items.length);
          }
        })
      }
    })
  } else {
    console.log("Got an error: ", error, ", status code: ", response.statusCode)
  }
});