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 。 我试图看看有多less具体项目属于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 } ] } } } } } } } 

我会用诺言来做这样的工作。 这将使任务的顺序非常清晰,并且您可以轻松读取不需要嵌套callback的代码。 在下面的例子中,我使用蓝鸟作为承诺,但是如果你坚持的话,你可以为自己实现“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 */ 

您正在asynchronous写入文件。 这意味着它将调用fs.writeFile ,然后继续而不用等待它完成。 由于写入文件系统花费的时间非常less,因此当fs.writeFile仍在执行时,程序将继续并调用其余的代码。

要解决这个问题,只需将其余的代码放入fs.writeFile的callbackfs.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) } });