node.js - JSON 响应中数组内容的顺序不一致

标签 node.js express es6-promise knex.js

所以,我在 Postgres 中有这个嵌套集合表,here's the schema and data 。我的 Express 应用程序中有以下 Controller 函数代码,用于使用 Knex 和一些 promise 处理将嵌套类别作为数组获取:

const getCategories = (req, res, db) => {
  const products = []

  db.raw(`
    SELECT child.id, child.name, child.path
    FROM product_category parent
    JOIN product_category child
    ON child.lower BETWEEN parent.lower AND parent.upper
    WHERE parent.id = 1
      AND
        (
          SELECT COUNT(*)
          FROM product_category node
          WHERE child.lower BETWEEN node.lower AND node.upper
            AND node.lower BETWEEN parent.lower AND parent.upper
        ) = 2 
  `)
  .then(categories => {
    if (categories.rows.length) {
      const categoryPromises = categories.rows.map(category => {
        return db.raw(`
          SELECT child.id, child.name, child.path
          FROM product_category parent
          JOIN product_category child
          ON child.lower BETWEEN parent.lower AND parent.upper
          WHERE parent.id = ${category.id}
          AND
            (
              SELECT COUNT(*)
              FROM product_category node
              WHERE child.lower BETWEEN node.lower AND node.upper
                AND node.lower BETWEEN parent.lower AND parent.upper
            ) = 2 
        `)
        .then(subcategories => {
          const categoryObject = { ...category, subcategories: [] }
          if (subcategories.rows.length) {
            subcategories.rows.map(subcategory => {
              categoryObject.subcategories.push(subcategory)
            })
            products.push(categoryObject)
          } else {
            res.status(400).json("No subcategories")
          }
        })
      })

      return Promise.all(categoryPromises)
      .then(() => res.json(products))

    } else {
      res.status(400).json("No categories")
    }
  })
}

我获得响应没有问题,但数组内第一级对象的顺序不一致。有时是这样的:

[
  {
    "id": 9,
    "name": "Other Products",
    "path": "other_products",
    "subcategories": [
      {
        "id": 10,
        "name": "Slides",
        "path": "slides"
      },
      {
        "id": 11,
        "name": "Buoys",
        "path": "buoys"
      }
    ]
  },
  {
    "id": 2,
    "name": "Boats",
    "path": "boats",
    "subcategories": [
      {
        "id": 3,
        "name": "Rescue Boats",
        "path": "rescue_boats"
      },
      {
        "id": 4,
        "name": "Dive Boats",
        "path": "dive_boats"
      },
      {
        "id": 5,
        "name": "Tamarans",
        "path": "tamarans"
      },
      {
        "id": 6,
        "name": "Dragon Boats",
        "path": "dragon_boats"
      },
      {
        "id": 7,
        "name": "Kayaks",
        "path": "kayaks"
      },
      {
        "id": 8,
        "name": "Speedboats",
        "path": "speedboats"
      }
    ]
  }
]

或者像这样:

[
  {
    "id": 2,
    "name": "Boats",
    "path": "boats",
    "subcategories": [
      {
        "id": 3,
        "name": "Rescue Boats",
        "path": "rescue_boats"
      },
      {
        "id": 4,
        "name": "Dive Boats",
        "path": "dive_boats"
      },
      {
        "id": 5,
        "name": "Tamarans",
        "path": "tamarans"
      },
      {
        "id": 6,
        "name": "Dragon Boats",
        "path": "dragon_boats"
      },
      {
        "id": 7,
        "name": "Kayaks",
        "path": "kayaks"
      },
      {
        "id": 8,
        "name": "Speedboats",
        "path": "speedboats"
      }
    ]
  },
  {
    "id": 9,
    "name": "Other Products",
    "path": "other_products",
    "subcategories": [
      {
        "id": 10,
        "name": "Slides",
        "path": "slides"
      },
      {
        "id": 11,
        "name": "Buoys",
        "path": "buoys"
      }
    ]
  }
]

如何使其保持一致?也许这有点微不足道,但过了一段时间就会变得有点烦人。提前致谢!

最佳答案

I also askedr/learnprogramming subreddit 以增加得到答复的机会。用户u/shhh-quiet给了一个nice solution

基本上,这是因为我在代码片段上写了错误的代码。我就引用他的整个答案:

I think it's that you're building the products array from inside the nested queries' promise chain. Depending on how long the queries take, products will end up with different orderings.

This is generally considered bad when working with promises. It basically breaks free of the ordering otherwise established by your use of map and Promise.all.

You should change:

products.push(categoryObject)

...to:

return categoryObject

And change:

return Promise.all(categoryPromises)
  .then(() => res.json(products))

...to:

return Promise.all(categoryPromises)
  .then(products => res.json(products))

And remove:

const products = []

编辑:需要明确的是,他没有 StackOverflow 帐户,但他允许我发布他的答案。

关于node.js - JSON 响应中数组内容的顺序不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55085175/

相关文章:

node.js - Socket.io如何检查客户端的cookie数据?

reactjs - 是否可以制作一个伪全局 promise 拒绝处理程序?

javascript - 如何通过调用构造函数。要求? "require(module)(CONSTRUCTOR)"?

javascript - 如何在命令行上访问 javascript 文件中的嵌套 js 对象

javascript - 外部文件中的 ExpressJS 导出路由不适用于根路径

javascript - 如何简化深层嵌套的 Promise

javascript - Javascript ES6 promise 支持 'done' api 吗?

node.js - Mongoose最新版本如何根据Date字段进行查询?

javascript - node.js 使用 Passport 登录

javascript - 使用下划线基于数组减少对象项