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) } });