javascript - 如何从 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;
解决方案
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
任何doc
s 值,但也匹配doc
's 键。如果doc
是一个复杂的嵌套文档,它也会匹配它们。用户当心。
推荐阅读
- swagger - 我如何表示'x-access-token:
' 在 Swagger 规范 (swagger.json) 中 - visual-studio-code - 在 VSCODE 中安装 PlatformIO 时出错 - ReadTimeoutError
- python - 连接到 Sharepoint
- sql - 计算每一行的空值加上其他条件
- asp.net-core - Razor 调试器在设置断点时冻结
- vue.js - 如何跳过第三步跳到第四步
- html - 固定在右上角的位置与父 div 相关
- openlayers - 为什么 optionsFromCapabilities 只存在于 WMTS 上?
- c# - 使用视图模型动态绑定 HTML 表 TH 失败
- python - 执行以下代码时出现值错误