首页 > 解决方案 > 如何从 for 循环在 Express JS 中发送 res.json()

问题描述

当从前端触发 API 调用时,我试图发送 json 响应,res.json()但当我从 for 循环获取数据时,我无法发送。我正在编写查询以在多个表中进行搜索。我正在使用 RethinkDB。

我想res.json()在查询后发送数据,但我不明白我在做什么错误。:(

提前感谢

热情

这是以下代码和小提琴链接

const express = require("express");
const router = express.Router();
const moment = require('moment');
const r = require('rethinkdb');
const tableNameDB = ['assets', 'alerts',  'destinations']


router.post('/', (req, res, next) => {
        let resData = []
        let searchValue = req.body.searchValue,
            tableName = req.body.tableName;
        newCallForSearch(res, searchValue, resData)
    })

function newCallForSearch (res, searchValue, resData){
    let anArray = ['captain']
    for(var i = 0; i<tableNameDB.length; i++){
        let tabName = tableNameDB[i]
        r.table(tableNameDB[i]).filter(function(doc) {
            return doc.coerceTo('string').match(searchValue);
        }).run(rethink_conn, (err, cur) => {
           // console.log(cur)
            if (err) {
                return 0
            } else {
                cur.toArray((err, result) => {
                    if (err) {
                        return 0
                    } else if (result) {
                        let Results = []
                        Results = Object.values(result).slice(0,10)
                        var newResults = Results.map(function() {
                            resData = Object.assign({'tableName': tabName},{'data' : result});
                            anArray.push(resData)
                        })
                    }
                })    
                
            }
                
        })
    }   
    res.status(200);
    res.json(anArray); 
}

module.exports = router;

标签: javascriptnode.jsexpressrethinkdb

解决方案


RethinkDb 是一个功能性数据库,因此以功能性方式使用它会产生最小的阻力。我们可以通过编写更少的代码来完成更多的工作。

您可以使用Promise.all运行许多子查询并将结果传递给res.send-

const search = (table = "", query = "", limit = 10) =>
  r.table(table)
  .filter(doc => doc.coerceTo("string").match(query))
  .toArray()
  .slice(0, limit)
  .do(data => ({ table, data }))

const tables =
  ['assets', 'alerts',  'destinations']

const subqueries =
  tables.map(t => search(t, "foo").run(rethink_conn)) // <-- search each table

Promise.all(subqueries) // <-- run all subqueries
  .then(result => {     // <-- handle success
    res.status(200)
    res.json(result)
  })
  .catch(e => {         // <-- handle failure
    res.status(500)
    res.send(e.message)
  })

或用于.union生成单个查询 -

const search = (table = "", query = "", limit = 10) =>
  r.table(table)
  .filter(doc => doc.coerceTo("string").match(query))
  .toArray()
  .slice(0, limit)
  .do(data => ({ table, data }))

const searchAll = (tables = [], query = "", limit = 10) =>
  tables.reduce
    ( (r, t) => r.union(search(t, query, limit)) // <-- union
    , r.expr([]) // <-- if no tables are supplied, return empty result
    )

const tables =
  ['assets', 'alerts',  'destinations']

searchAll(tables, "foo") // <-- single rethink expr
  .run(rethink_conn)     // <-- run returns a promise
  .then(result => {      // <-- handle success
    res.status(200)
    res.json(result)
  })
  .catch(e => {          // <-- handle failure
    res.status(500)
    res.send(e.message)
  })

我应该filter在您原来的帖子中建议使用 -

.filter(doc => doc.coerceTo("string").match(query))

这很快,但也很草率。它匹配query任何docs 值,但也匹配doc's 键。如果doc是一个复杂的嵌套文档,它也会匹配它们。用户当心。


推荐阅读