您如何 return mongodb 向浏览器发送 hapi.js 路由处理程序中的信息?
How do you return mongodb info to the browser inside a hapi.js route handler?
我刚刚开始使用 hapi.js (^17.3.1) 和 mongodb (^3.0.7),以及异步 js 代码。
在路由处理程序中,我正在尝试从数据库中检索数据。作为测试,我将一个字符串存储在一个变量 "s" 中,该变量是通过遍历数据库集合记录构建的。浏览器的预期输出是
start dbInfo1 dbInfo2 dbInfoN end
我试过此代码的各种版本:
module.exports = {
method: 'GET',
handler: async function (request, reply) {
return await getRoutes();
}
}
async function getRoutes() {
var s = "start";
const mongo = require('mongodb').MongoClient;
const mongoUrl = "mongodb://127.0.0.1:27017/";
return // I'm returning this whole thing because hapi.js says it wants a promise. (500 error)
await mongo.connect(mongoUrl)
.then(function(client) {
client.db("dbName").collection("collectionName")
.find({})
.forEach(function (record) {
console.log(record.item);
s += " | " + record.item;
});
s + " end"; // But I've tried placing "return" here (500 error)
});
// I've also tried ".then(function(s) { return s + 'end' }) here but it seems to only have the same set of options/problems manifest.
// I've also made it so that I place "return s + 'end'" here (displays "start end" with nothing in the middle).
}
我试过将 return 语句放在不同的地方。我要么在控制台中收到 http 500 错误
Debug: internal, implementation, error
Error: handler method did not return a value, a promise, or throw an error
dbInfo1
dbInfo2
dbInfoN
如果我 return 承诺本身或来自承诺内部,或者我得到
start end
在浏览器中,如果我 return 来自 promise 之外。
在任何一种情况下,console.log 语句都会打印出 dbInfos 输出。
我尝试了 async 和 await 的不同放置、包含和省略,结果几乎相同。我还尝试使用 "new Promise(..." 将 getRoutes 中正在 returned 的内容包装到显式 Promise 中。在这种情况下,控制台会记录 dbInfos,但浏览器会挂起。
如何在 return 变量 s 之前等待 "foreach" 函数?
未经测试,我可以说这是错误的:
return // I'm returning this whole thing because hapi.js says it wants a promise. (500 error)
await mongo.connect(mongoUrl)
.then(function(client) {
client.db("dbName").collection("collectionName")
.find({})
.forEach(function (record) {
console.log(record.item);
s += " | " + record.item;
});
s + " end"; // But I've tried placing "return" here (500 error)
});
return 被解析为 return;
return await mongo.connect(mongoUrl)
.then(function(client) {
client.db("dbName").collection("collectionName")
.find({})
.forEach(function (record) {
console.log(record.item);
s += " | " + record.item;
});
s + " end"; // But I've tried placing "return" here (500 error)
});
是正确的方法。任何 linter 都会警告你。
终于!使用此代码得到它:
module.exports = {
method: 'GET',
handler: function (request, reply) {
return getRoutes();
}
}
function getRoutes() {
const mongo = require('mongodb').MongoClient;
const mongoUrl = "mongodb://127.0.0.1:27017/";
return mongo.connect(mongoUrl)
.then(async function(client) {
var s = "start";
var documents = await
client.db("dbName").collection("collectionName")
.find()
.toArray();
for (const doc of documents)
s += " | " + await doc.item;
return s + " end";
});
}
问题是我认为由于 "getRoutes" 被标记为 "async",“.then” 中的内容也是异步的。但我确实需要将 "function(client)" 标记为 "async"。我还需要停止使用 "forEach" 并在集合上使用更传统的迭代。
我之前其实把"function(client)"标记为"async",但那是盲目的试错,所以一直没用好"await"。直到阅读 this Anton Lavrenov 的博客,我才真正开始理解它。
虽然我最近才问这个问题,但在那之前我已经研究了很长时间了。对我现在所处的位置真的很满意。当然,感谢@desoares 指出我在上面使用的代码版本中的愚蠢错误。
我刚刚开始使用 hapi.js (^17.3.1) 和 mongodb (^3.0.7),以及异步 js 代码。
在路由处理程序中,我正在尝试从数据库中检索数据。作为测试,我将一个字符串存储在一个变量 "s" 中,该变量是通过遍历数据库集合记录构建的。浏览器的预期输出是
start dbInfo1 dbInfo2 dbInfoN end
我试过此代码的各种版本:
module.exports = {
method: 'GET',
handler: async function (request, reply) {
return await getRoutes();
}
}
async function getRoutes() {
var s = "start";
const mongo = require('mongodb').MongoClient;
const mongoUrl = "mongodb://127.0.0.1:27017/";
return // I'm returning this whole thing because hapi.js says it wants a promise. (500 error)
await mongo.connect(mongoUrl)
.then(function(client) {
client.db("dbName").collection("collectionName")
.find({})
.forEach(function (record) {
console.log(record.item);
s += " | " + record.item;
});
s + " end"; // But I've tried placing "return" here (500 error)
});
// I've also tried ".then(function(s) { return s + 'end' }) here but it seems to only have the same set of options/problems manifest.
// I've also made it so that I place "return s + 'end'" here (displays "start end" with nothing in the middle).
}
我试过将 return 语句放在不同的地方。我要么在控制台中收到 http 500 错误
Debug: internal, implementation, error
Error: handler method did not return a value, a promise, or throw an error
dbInfo1
dbInfo2
dbInfoN
如果我 return 承诺本身或来自承诺内部,或者我得到
start end
在浏览器中,如果我 return 来自 promise 之外。
在任何一种情况下,console.log 语句都会打印出 dbInfos 输出。
我尝试了 async 和 await 的不同放置、包含和省略,结果几乎相同。我还尝试使用 "new Promise(..." 将 getRoutes 中正在 returned 的内容包装到显式 Promise 中。在这种情况下,控制台会记录 dbInfos,但浏览器会挂起。
如何在 return 变量 s 之前等待 "foreach" 函数?
未经测试,我可以说这是错误的:
return // I'm returning this whole thing because hapi.js says it wants a promise. (500 error)
await mongo.connect(mongoUrl)
.then(function(client) {
client.db("dbName").collection("collectionName")
.find({})
.forEach(function (record) {
console.log(record.item);
s += " | " + record.item;
});
s + " end"; // But I've tried placing "return" here (500 error)
});
return 被解析为 return;
return await mongo.connect(mongoUrl)
.then(function(client) {
client.db("dbName").collection("collectionName")
.find({})
.forEach(function (record) {
console.log(record.item);
s += " | " + record.item;
});
s + " end"; // But I've tried placing "return" here (500 error)
});
是正确的方法。任何 linter 都会警告你。
终于!使用此代码得到它:
module.exports = {
method: 'GET',
handler: function (request, reply) {
return getRoutes();
}
}
function getRoutes() {
const mongo = require('mongodb').MongoClient;
const mongoUrl = "mongodb://127.0.0.1:27017/";
return mongo.connect(mongoUrl)
.then(async function(client) {
var s = "start";
var documents = await
client.db("dbName").collection("collectionName")
.find()
.toArray();
for (const doc of documents)
s += " | " + await doc.item;
return s + " end";
});
}
问题是我认为由于 "getRoutes" 被标记为 "async",“.then” 中的内容也是异步的。但我确实需要将 "function(client)" 标记为 "async"。我还需要停止使用 "forEach" 并在集合上使用更传统的迭代。
我之前其实把"function(client)"标记为"async",但那是盲目的试错,所以一直没用好"await"。直到阅读 this Anton Lavrenov 的博客,我才真正开始理解它。
虽然我最近才问这个问题,但在那之前我已经研究了很长时间了。对我现在所处的位置真的很满意。当然,感谢@desoares 指出我在上面使用的代码版本中的愚蠢错误。