Node.js 节点中嵌套读取文件的承诺模式
我对node和promises还不熟悉,但我感到困惑 我正在阅读一个json,其中包含我需要阅读的其他json文件的信息。看起来是这样的:Node.js 节点中嵌套读取文件的承诺模式,node.js,promise,Node.js,Promise,我对node和promises还不熟悉,但我感到困惑 我正在阅读一个json,其中包含我需要阅读的其他json文件的信息。看起来是这样的: { id: 1, name: "My name", includes: [ "#include1.json", "#include2.json", "#include3.json" ] } { id: 1, name: "Include 1", det
{
id: 1,
name: "My name",
includes: [
"#include1.json",
"#include2.json",
"#include3.json"
]
}
{
id: 1,
name: "Include 1",
details: "I am include 1"
}
{
id: 1,
name: "My name",
includes: [
{
id: 1,
name: "Include 1",
details: "I am include 1"
},
{
id: 2,
name: "Include 2",
details: "I am include 2"
},
{
id: 3,
name: "Include 3",
details: "I am include 3"
},
]
}
包含文件如下所示:
{
id: 1,
name: "My name",
includes: [
"#include1.json",
"#include2.json",
"#include3.json"
]
}
{
id: 1,
name: "Include 1",
details: "I am include 1"
}
{
id: 1,
name: "My name",
includes: [
{
id: 1,
name: "Include 1",
details: "I am include 1"
},
{
id: 2,
name: "Include 2",
details: "I am include 2"
},
{
id: 3,
name: "Include 3",
details: "I am include 3"
},
]
}
我需要做的是读取主json,然后用所有给定的include构建一个完整的json文档,因此它将如下所示:
{
id: 1,
name: "My name",
includes: [
"#include1.json",
"#include2.json",
"#include3.json"
]
}
{
id: 1,
name: "Include 1",
details: "I am include 1"
}
{
id: 1,
name: "My name",
includes: [
{
id: 1,
name: "Include 1",
details: "I am include 1"
},
{
id: 2,
name: "Include 2",
details: "I am include 2"
},
{
id: 3,
name: "Include 3",
details: "I am include 3"
},
]
}
主json文件将指定包含的内容
我将readFile方法放入一个返回承诺的函数中
function readFile(filename, enc, err){
return new Promise(function (fulfill, reject){
if(err) reject(err);
fs.readFile(filename, enc, function (err, res){
if (err) reject(err);
else fulfill(res);
});
});
}
而我的服务文件会使用它
serviceReturnJsonPromise = function() {
return readFile(masterPath, 'utf8', err).then(function (masterData){
return JSON.parse(masterData);
});
}
返回主json OK
但现在我还是坚持使用包含的内容
serviceReturnJsonPromise = function() {
return readFile(masterPath, 'utf8', err).then(function (masterData){
var master = JSON.parse(masterData);
var includes = [];
_.each(master.includes, function(include) {
var includePath = "./" + item.replace("#","");
return readFile(includePath, 'utf8', err).then(function (includeData){
includes.push(JSON.parse(includeData));
});
});
});
}
你可以看到它还没有完成,但这一点不起作用,因为承诺没有堆积起来。我知道我会用所有的东西来堆积承诺,但我不知道在我读到大师之前,承诺会是什么
如果你们能给我一个学习node的好起点,我将不胜感激。当你们试图阅读includes时,你们错了,不要等待结果。在读取第一个include文件之前,将使用零数据解析承诺 这应该起作用:
serviceReturnJsonPromise = function () {
return readFile(masterPath, 'utf8', err)
.then(function (masterData) {
var master = JSON.parse(masterData);
// map over includes array and return "read" promises
var includes = master.includes.map(function (item) {
var includePath = "./" + item.replace("#", "");
return readFile(includePath, 'utf8', err).then(function (includeData) {
return JSON.parse(includeData)
});
});
// wait for all file reads
return Promise.all(includes).then(jsons=>{
master.includes = jsons;
return master;
})
});
}
有一个很好的解释承诺
另外,也请查看该频道,这里有很多解释得很好的js主题。@EricP因为您只想使用json导入,您可以直接
要求它们,而无需使用fs
模块。事情会是这样的-
const path = require('path')
const main = require(path.resolve('main.json'))
const readFile = (children) => {
const result = children.map((file) => {
const child = require(path.resolve(file))
if(child.includes){
child.includes = readFile(child.includes)
}
return child
})
children.includes = result
return result;
}
console.dir(readFile(main.includes), {depth: null})
解释
readFile实用程序(可以更好地命名)递归解析includes树并将结果设置回原来的位置
希望这有帮助。查看承诺。所有都不要使用forEach
(或)。每个)。使用map
,您甚至不必使用push
。使用Promise.all
在数组中收集单个承诺(每个文件的结果)后。可以在此处找到正在运行的repl-以这种方式重新读取文件是不可能的,至少在没有缓存损坏的情况下是不可能的。不知道这段代码的上下文是什么,也不知道这是否是一个问题。但这一点应该考虑在内。谢谢你的帮助,这就解决了问题。视频也是一个很好的资源,值得称赞。