Node.js 节点中嵌套读取文件的承诺模式

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

我对node和promises还不熟悉,但我感到困惑

我正在阅读一个json,其中包含我需要阅读的其他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"
        },
    ]
}
包含文件如下所示:

{ 
    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-以这种方式重新读取文件是不可能的,至少在没有缓存损坏的情况下是不可能的。不知道这段代码的上下文是什么,也不知道这是否是一个问题。但这一点应该考虑在内。谢谢你的帮助,这就解决了问题。视频也是一个很好的资源,值得称赞。